Search code examples
iosobjective-ccore-textnsattributedstringspannablestring

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


Im on an iOS app that should able to highlight text, and make it clickable too.

I read about NSAttributedString in iOS but it still more complicated than Spannable in android.

Is there any other Objective c way to do that, if not; what should i do using NSAttributedString to highlight a paragraph word by word, and how to make my text clickable.

Update:

What exactly i want that each word should be clickable and can be highlighted as a single word in one paragraph.


Solution

  • 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.