Domanda

I would like to highlight or underline a specific set of words in a NSString. I am able to detect if the words exist, I'm just not able to get them highlighted.

NSString * wordString = [NSString stringWithFormat:@"%@", [self.myArray componentsJoinedByString:@"\n"]];

self.myLabel.text = wordString;

if ([wordString rangeOfString:@"Base Mix"].location == NSNotFound)
{
    NSLog(@"string does not contain base mix");
}
else
{
    NSLog(@"string contains base mix!");

    NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:wordString];

    NSString * editedString = [NSString stringWithFormat:@"%lu", (unsigned long)[wordString rangeOfString:@"Base Mix"].location];

    NSRange theRange = NSMakeRange(0, [editedString length]);

    [string beginEditing];
    [string removeAttribute:NSForegroundColorAttributeName range:theRange];
    [string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:theRange];
    [string endEditing];

    [self.myLabel setAttributedText:string];
}

This code is closer to the right path. I do see a highlighted character, but it's the very first character in the string and not the words that I have searched for.

È stato utile?

Soluzione

You can use the NSUnderlineStyleAttributeName and NSUnderlineColorAttributeName attributes. I think you can use it like this:

NSRange foundRange = [wordString rangeOfString:@"Base Mix"];
if (foundRange.location != NSNotFound)
{
    [wordString beginEditing];
    [wordString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:1] range:foundRange];
    [wordString addAttribute:NSUnderlineColorAttributeName value:[NSColor redColor] range:foundRange];
    [wordString endEditing];
}

Altri suggerimenti

You can use below code which relate to NSAttributed string. works only ios6+

NSString *tem = @"String with base Mix dfsdfsd ";
 NSString *substring = @"base Mix";
 NSRange range;
 if ((range =[tem rangeOfString:substring]).location == NSNotFound)
 {
       NSLog(@"string does not contain base mix");
 }
 else
 {
       NSMutableAttributedString *temString=[[NSMutableAttributedString alloc]initWithString:tem];
       [temString addAttribute:NSUnderlineStyleAttributeName
                                  value:[NSNumber numberWithInt:1]
                                  range:(NSRange){range.location,substring.length}];
        NSLog(@"%@",temString);
       self.yourLabel.attributedText = temString;
 }     

I think the part is missing from NSAttributedString. You can try with Three20

You could create an category method of NSString class like this

-(NSMutableAttributedString*)addAttributesToWords:(NSString*)string attributes:(NSArray*)attributes {
    NSRange range;
    if ((range = [self rangeOfString:string]).location == NSNotFound){
        return [[NSMutableAttributedString alloc] initWithString:self];
    }
    else{
        NSMutableAttributedString *result = [[NSMutableAttributedString alloc] initWithString:self];
        for (NSDictionary *attribute in attributes) {
            [result addAttributes:attribute range:range];
        }
        return result;
    }
}

How to use it::

NSArray *attributes = @[@{NSFontAttributeName : kFont_OpenSansSemiBold14},
                        @{NSForegroundColorAttributeName : [UIColor darkGrayColor]}];

self.label.attributedText = [@"Hello There, this is a Test" addAttributesToWords:@"Hello There" attributes:attributes];

With the help of @user1118321's answer, I wrote this function and I would hope it saves someone's time.

func highlightedString(allText:String,toBeHighlighted word:String) -> NSAttributedString{
        
        var putInString = NSMutableAttributedString.init()
        var giveFrom = NSMutableString.init(string: allText)
        
        while true {
            let range = giveFrom.range(of: word)
            let index = range.location + range.length
            if range.location == NSNotFound{
                putInString.append(NSAttributedString.init(string: giveFrom as String))
                break
            }
            else{
                let slite = giveFrom.substring(to: index)
                let highlightedSlite = NSMutableAttributedString.init(string: slite)
                highlightedSlite.addAttributes([NSAttributedStringKey.backgroundColor : UIColor.yellow], range: range)
                giveFrom = giveFrom.substring(from: index) as! NSMutableString
                putInString.append(highlightedSlite)
            }
        }
        return putInString
    }

Maybe it is not very clear code. I welcome any suggested edits that would help.

highlight Many words

func higlighted(allText:String,words:[String]) ->NSAttributedString{
        
        let allAttributedText = NSMutableAttributedString.init(string: allText)
        var ranges = [NSRange]()
        
        for word in words{
            var string = allAttributedText.string as NSString
            var i = 0
            while true {
                var range = string.range(of: word)
                if range.location == NSNotFound {
                    break
                }
                i = i + range.location + word.count
                string = string.substring(from: range.location + range.length) as NSString
                range.location = i - word.count
                print("\(range)  XX \(word)" )
                
                ranges.append(range)
            }
        }
        for range in ranges{
            allAttributedText.addAttributes([NSAttributedStringKey.backgroundColor : UIColor.yellow], range: range)
        }
        return allAttributedText
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top