Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 435
Jan Cássio Avatar asked Oct 19 '25 11:10

Jan Cássio


1 Answers

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,

like image 60
Jan Cássio Avatar answered Oct 21 '25 02:10

Jan Cássio