5

I have a UITextView that spans 100.0 points across my UIView.

In the UITextView, I have links that get captured with the following function:

- (BOOL) textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange

This works great to capture certain characters but I have one problem: if the link is the last characters in the text view, then the tap will get pressed all the way across that line.

So if I have the text view with the following text where @test is the link:

// The entire remainder of the line will be the link (all the white space after @test)
Hello @test

How do I fix this?

Nikunj
  • 655
  • 3
  • 13
  • 25
cdub
  • 24,555
  • 57
  • 174
  • 303
  • Means you want the blank space to open the link? – Sohil R. Memon Jan 16 '16 at 10:41
  • Will it highlight the remaining if the `@test` link trails with a whitespace? Is it happen on iOS 9 only? – chubao Jan 16 '16 at 14:44
  • I DO NOT want anything after @test to be linkable but by default it is – cdub Jan 18 '16 at 05:31
  • 2
    Try with adding `[[NSAttributedString alloc] initWithString:@"\u2063" attributes:nil]` at the end of your `NSAttributedString`. – Larme Jan 21 '16 at 10:22
  • cool that does work. i think it helps with the attributes:nil. I can see why they made the bounds as it's harder to click now – cdub Jan 21 '16 at 10:29

3 Answers3

2

For me it only highlights the link... Am I missing something?

enter image description here

Update:

Here's a really hacky solution via dummy URL's:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSMutableAttributedString* attributedString = [[NSMutableAttributedString alloc] init];
    [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"Lorem ipsum dolor sit amet, vim iuvaret blandit intellegebat ut. Solet diceret interpretaris eos cu, magna dicat explicari mei ex, cibo adversarium eu pro. Ei odio saepe eloquentiam cum, nisl case nec ut. Harum habemus definiebas et vix, est cu aeque sonet, in his salutatus repudiare deterruisset. Quo duis autem intellegat an, regione propriae et vis."]];

    NSAttributedString* dummyUrl = [[NSAttributedString alloc] initWithString:@" " attributes:@{ NSLinkAttributeName : @"http://dummy.com" }];
    NSAttributedString* url = [[NSAttributedString alloc] initWithString:@"http://stackoverflow.com" attributes:@{ NSLinkAttributeName : @"http://stackoverflow.com" }];
    [attributedString appendAttributedString:dummyUrl];
    [attributedString appendAttributedString:url];
    [attributedString appendAttributedString:dummyUrl];
    self.textView.attributedText = attributedString;
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    return ![URL.absoluteString isEqualToString:@"http://dummy.com"];
}

Basically you force the UITextView to recognise the tap before and after the stackoverflow link as the dummy link. Since it's just a space it's invisible, however unfortunately if you tap and hold before/after the stackoverflow link you'll see the space highlighted with gray, despite shouldInteractWithURL returning NO. Unfortunately it seems you cannot circumvent this behaviour unless you implement your own UITextField from scratch...

Tamás Zahola
  • 9,271
  • 4
  • 34
  • 46
  • yes but what if you tap/click 20 points to the right of .com that is highlighted? – cdub Jan 21 '16 at 10:04
  • I see what you mean. But it's not just the area after the link, it's also the area to the left, above and below the link. Basically the tap area of the link extends beyond the visible boundary (if no other link is nearby) to make tapping on the link easier. I'd be surprise if you could customise this behaviour. – Tamás Zahola Jan 21 '16 at 10:11
  • so essentially leave it alone and don't touch (i.e. they won't let you) – cdub Jan 21 '16 at 10:14
  • 1
    just noticed you work at prezi? cool software we used to present and get a job – cdub Jan 21 '16 at 10:14
  • @chris either you have to accept this behaviour, or try the hack I've updated my answer with. Honestly, I'd recommend the former. Also, keep on using prezi! :) – Tamás Zahola Jan 21 '16 at 10:30
  • Accept the behavior is probably best. And accept the bounty. Are you in SF? – cdub Jan 21 '16 at 10:32
  • Nope, I'm in Hungary. Maybe I'll visit SF soon, we'll see. – Tamás Zahola Jan 21 '16 at 10:33
  • Ah I see, crunchbase has you in the budapest office. Thx for your help. Off to bed as its late in SF. – cdub Jan 21 '16 at 10:35
  • You are adding an extra space. This behavior may create a new line (for example in case of UITextView adapting its size to its content (especially the height), while in case of adding a invisible space, it should do the trick. Plus, I'd avoid setting at all an attribute for the space, it's just useless. – Larme Jan 21 '16 at 10:40
2

As Tamás Zahola suggested in previous answer, you can fix this issue by adding "dummy" URLs before and after real URL. But, instead using whitespace in dummy link, use zero width space unicode character:

NSAttributedString* dummyUrl = [[NSAttributedString alloc] initWithString:@"\u200B" attributes:@{ NSLinkAttributeName : @"http://dummy.com" }];
[attributedString appendAttributedString:dummyUrl];
[attributedString appendAttributedString:url];
[attributedString appendAttributedString:dummyUrl];
Borys Verebskyi
  • 4,160
  • 6
  • 28
  • 42
0

enter image description here You simply need to set some properties after linking that textView to code like textview delegate, editable and dataDetectorTypes

Below i have added the content i have used

Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson3.html Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. http://stackoverflow.com Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda http://stackoverflow.com

for objective-c

textView.delegate=self:
textView.editable = NO;  
textView.dataDetectorTypes = UIDataDetectorTypeLink;


- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
   return true;

}

for Swift

textView1.delegate=self
textView1.editable = false
textView1.dataDetectorTypes = UIDataDetectorTypes.Link

func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
    return true
}