Search code examples
iosuibuttonnsattributedstring

iOS: Add Button over NSAttributedString


I want to know if is possible to put a UIButton over a exactly coordinate of a piece of text.

For example, my UILabel have this text:

"Dont have an account? Sign In"

In the italic content, I need to put a button over then, the touch over this button will trigger an action that will open a Sign In View

Is very important to make this feature well, to work with same in other languages without do anything :)

Thanks


Solution

  • I'll respond my answer because this can be helpful for other developers that got the same problem.

    1: You need to implement UITextViewDelegate method: - (BOOL)textView:shouldInteractWithURL:inRange:

    The implementation is very simple, basically, you will compare the received link in NSURL. I like to compare by host using the NSURL components when I have many links, for example:

    - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
    {
      NSString *urlScheme     = URL.scheme;
      NSString *host          = URL.host;
    
      if([urlScheme isEqualToString:@"myapp"])
      {
        if([host isEqualToString:@"/signin"])
          [self.onSignRequest( self )];
      }
    
      return YES;
    }
    

    This method will be called when user touch over link.

    2: Create two NSString instances, one for the string "Don't have an account?" and another one for string "Sign Up"

    NSString *labelText = @"Don't have an account? ";
    NSString *linkedText = @"Sign Up";
    

    3: Create a NSMutableAttributedString instance with both strings concated:

    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[AttributedText attributedStringWithText:[NSString stringWithFormat:@"%@%@", labelText, linkedText]
                                                                                                                                              font:[UIFOnt systemFontOfSize:14.f]
                                                                                                                                             color:[UIColor blueColor]]];
    

    4: Create a range for a linked text from the mutable attributed string created before:

    NSRange range = [[attributedString  string] rangeOfString:linkedText];
    

    5: Create an string to

    5: Add a new NSLinkAttributeName for the mutable string with the range created in step 4

    [attributedString addAttribute:NSLinkAttributeName value:URLStringLink range:range];
    

    6: Add the mutable string to UILabel using attributedText property of UILabel

    _label.attributedText = attributedText;
    

    7: Set the delegate of label:

    _label.delegate = textViewDelegate;
    

    And that's it. I hope this can be helpful for anyone needs to add "touchable" links in UILabel

    Cheers,