What is the equivalent of Android's “Spannable” in Objective-C

被刻印的时光 ゝ 提交于 2019-11-28 19:48:02

I found a perfect solution using UITextView, it will make every word in within the UITextView clickable.

Firstly, Create an UITextView and add an UITapGestureRecognizer to it as follows:

CGRect textViewFrame = CGRectMake(0, 40, 100, 100);
textView = [[UITextView alloc]initWithFrame: textViewFrame];
textView.textAlignment = NSTextAlignmentCenter;
textView.backgroundColor = [UIColor clearColor];
textView.editable = NO;
textView.selectable = NO;

[self.view addSubView:textView];

// i used to `NSMutableAttributedString` highlight the text

 string = [[NSMutableAttributedString alloc]initWithString:@"Any text to detect A B $ & - +"];
    [string addAttribute:NSFontAttributeName
                  value:[UIFont systemFontOfSize:40.0]
                  range:NSMakeRange(0, [string length])];
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init] ;
    [paragraphStyle setAlignment:NSTextAlignmentCenter];

    [string addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [string length])];

    [textView setAttributedText:string];

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRecognized:)];

//modify this number to recognizer number of tap
[singleTap setNumberOfTapsRequired:1];
[textView addGestureRecognizer:singleTap];

Then add the UITapGestureRecognizer @selector:

- (void)tapRecognized:(UITapGestureRecognizer *)recognizer{

    if(recognizer.state == UIGestureRecognizerStateRecognized)
    {

        CGPoint point = [recognizer locationInView:recognizer.view];
        NSString * detectedText = [self getWordAtPosition:point inTextView: textView];

        if (![detectedText isEqualToString:@""]) {

    NSLog(@"detectedText  == %@", detectedText);


        } }

}

All this magic is related to this method, witch can detect any touch on the UITextView and get the tapped word:

-(NSString*)getWordAtPosition:(CGPoint)pos inTextView:(UITextView*)_tv
{
    //eliminate scroll offset
    pos.y += _tv.contentOffset.y;

    //get location in text from textposition at point
    UITextPosition *tapPos = [_tv closestPositionToPoint:pos];

    //fetch the word at this position (or nil, if not available)
    UITextRange * wr = [_tv.tokenizer rangeEnclosingPosition:tapPos withGranularity:UITextGranularityWord inDirection:UITextLayoutDirectionRight];

    return [_tv textInRange:wr];
}

And for highlighting the text:

-(void)setTextHighlited :(NSString *)txt{

    for (NSString *word in [textView.attributedText componentsSeparatedByString:@" "]) {

        if ([word hasPrefix:txt]) {
            NSRange range=[self.textLabel.text rangeOfString:word];
            [string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:range];
         }}
    [textView setAttributedText:string];

}

And thats it, hope this helps others.

Unfortunately the behavior that you're looking for isn't as simple in objective-c as Spannable.

However, it can be accomplished fairly easily:

  1. Create a UILabel or UITextView.
  2. Highlight some of the words using NSMutableAttributedString and NSRange (see below).
  3. Apply the attributed string to the attributedText property.
  4. Create UIButtons with clear backgrounds and no label and position over the top of the clickable words.
  5. Add a target to each button and create a selector method.

Here's some example code for the attributed string to get you started:

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:  [NSString stringWithFormat:@"Text containing a bold word and another"];
[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14] range:NSMakeRange(18,4)];
[string addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:14] range:NSMakeRange(32, 7)];
label.attributedText = string; 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!