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

2

11

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.

Surfboard answered 18/11, 2013 at 9:24 Comment(7)
The easiest way is probably to load HTML in a UIWebViewKrakow
I want to do it natively, using objective cSurfboard
possible duplicate of Can't make URL clickable in UITextViewElyse
No its not duplicated, because in searching for Spannable equivalent (each word should be clickable and can be highlighted as a single word), read the question !!!!Surfboard
If you read the answer there are quite a few hints in there to help. Or are you just waiting for someone to give you the few lines of code you need?Elyse
you are probably searching for the wrong thing. in order for something to be "clickable" in cocoa-touch it needs to descend from UIResponder. you need some type of view that can display an attributed string.Ways
Ive figured a solution, and I've posted it as an answerSurfboard
S
13

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.

Surfboard answered 24/11, 2013 at 5:30 Comment(0)
S
0

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; 
Sells answered 22/11, 2013 at 16:30 Comment(2)
I have more than 1000 words, its to heavy !!Surfboard
In that case there are only 2 options left to you: Format your text asa html and use a UIWebView or find a library in which somebody has already solved this problem.Sells

© 2022 - 2024 — McMap. All rights reserved.