1

In my app I am reading in from a text file on a server. When I get this NSString I want to basically make different parts of it clickable so that if they click on a certain sentence, then it will open a dialog box. How would I go about this?

I have read about using UITapGestureRecognizer but I am not sure how I could use that to recognize a string of text rather than just a single word at a time.

I have also looked into NSMutableAttributedStrings but I am just not finding what I need to make sense of how to do this.

Any help would be appreciated.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
sabo
  • 911
  • 13
  • 37
  • Have you read that [SO question](http://stackoverflow.com/questions/21629784/make-a-clickable-link-in-an-nsattributedstring-for-a-uitextfield-or-uilabel)? – Azat Apr 22 '15 at 19:40
  • @Azat Those use a URL and I can't figure out how to use a method call instead. – sabo Apr 22 '15 at 20:54
  • Your essential mistake is that neither `NSString` nor `NSAttributedString` has no UI part and user can't interact with them. So generally said, the answer for your current question formulation is "it is not possible". However, if you clarify it by adding how you are displaying it, at `UILabel`, `UITextView`, general `UIView` or whatever, you probably will get reasonable answer – Azat Apr 23 '15 at 07:38

1 Answers1

0

You can use an NSAttributedString to insert a link with a custom URL scheme. Then, when you detect that the link has been pressed, check the url scheme and if it's yours, do whatever you want to do in that method. You will have to use an UITextView, or you can also use a TTTAttributedLabel (you can find the TTTAttributedLabel here). The following sample code (inspired from older Ray Wenderlich article) uses a UITextView.

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Something should happen when you press _here_"];
[attributedString addAttribute:NSLinkAttributeName
                         value:@"yoururlscheme://_here_"
                         range:[[attributedString string] rangeOfString:@"_here_"]];

NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor greenColor],
                             NSUnderlineColorAttributeName: [UIColor lightGrayColor],
                             NSUnderlineStyleAttributeName: @(NSUnderlinePatternSolid)};

// assume that textView is a UITextView previously created (either by code or Interface Builder)
textView.linkTextAttributes = linkAttributes; // customizes the appearance of links
textView.attributedText = attributedString;
textView.delegate = self;

Then, to actually catch the tap on the link, implement the following UITextViewDelegate method:

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
    if ([[URL scheme] isEqualToString:@"yoururlscheme"]) {
        NSString *tappedWord = [URL host]; 
        // do something with this word, here you can show your dialogbox
        // ...
        return NO; // if you don't return NO after handling the url, the system will try to handle itself, but won't recognize your custom urlscheme
    }
    return YES; // let the system open this URL
}

I find UITextView with NSAttributedString and custom URLs to be quite powerful, you can do a lot of things with them, you can also send parameters through your url, which can be very convenient sometimes.

You can change the url scheme to something that makes more sense in your case (instead of the yoururlscheme). Just be sure to change it both when you create the URL and when you handle it and check for the url scheme. You can also have multiple url schemes, for example, if you want to have multiple behaviours when tapping on text in your textview.

  • I gave that a shot but now I have an error that says something along the lines of: assigning to 'id uitextviewdelegate ' from incompatible type. I have gone into my view controller header and have added the but no luck. – sabo Apr 27 '15 at 16:36