iloveios
iloveios

Reputation: 37

Highlighting some text in a TextField differently

I'm creating a recipe by ingredient app. When I type the ingredients on the textfield and then press the find a recipe button it downloads recipes with those typed ingredients but it displays additional ingredients on the label and what I want to do is to display the label with the typed ingredients in different color from the additional ingredients.

example code:

-(void)drawTheCell:(Recipe *)recipeObject {

    self.recipeTitle.text = recipeObject.title;

    NSArray *dividesString = [recipeObject.ingredients componentsSeparatedByString:@", "];

    NSMutableString *listIngreditents;
    for (int i=0; i < dividesString.count; i++) {


        for(int j=0; i < recipeObject.keywords.count || j < i; j++) {
        if ([dividesString objectAtIndex:i] == [recipeObject.keywords objectAtIndex:i]) {
                self.recipeIngredients.text = [dividesString objectAtIndex:i];
                self.recipeIngredients.textColor = [UIColor greenColor];

                [listIngreditents appendString:self.recipeIngredients.text];
                NSLog(@"Found a match");

            }
            else {
                    [listIngreditents appendString:[dividesString objectAtIndex:i]];
            }
    }

the label doesn't display the ingredients but it does displays the recipes without the the ingredients.

Upvotes: 2

Views: 134

Answers (2)

Lyndsey Scott
Lyndsey Scott

Reputation: 37290

Other than the fact that as Fennelouski mentioned, you're not using an attributed string, there are a lot of issues with your logic.

Your current inner loop probably won't do what you expect it to do... Basically, the inner loop is only going to execute when either the recipeObject index is less than the current dividesString index or the current dividesString index is less than the total number of keywords and generally speaking, with this logic, you've basically created dependencies that make no sense in what you're attempting to accomplish.

Instead, what you want to do is see whether your current dividesString matches any keyword currently in the text field, so if wanted to code the logic you're attempting by using a double loop, you could loop through all the keywords during each iteration of the outer loop and do your if-else comparison after the inner loop finishes executing, ex:

- (void)drawTheCell:(Recipe *)recipeObject {

    self.recipeTitle.text = recipeObject.title;

    // Break up the recipe ingredients into components
    NSArray *dividesString = [recipeObject.ingredients componentsSeparatedByString:@", "];

    // Create a mutable attributed string so you can maintain
    // color attributes
    NSMutableAttributedString *listIngredients = [[NSMutableAttributedString alloc] init];

    // Loop through the ingredient components
    for (int i=0; i < dividesString.count; i++) {

        // Add a comma if it's not the first ingredient
        if (i > 0) {
             NSMutableAttributedString *commaString = [[NSMutableAttributedString alloc] initWithString:@", "];
            [listIngredients appendAttributedString:commaString];
        }

        // Create a boolean to indicate whether a keyword match
        // has been found
        bool matchFound = NO;

        // Loop through your "keywords"
        for(int j=0; j < recipeObject.keywords.count; j++) {

            // If the current ingredient matches the current keyword
            // change the matchFound boolean to true
            if ([[dividesString objectAtIndex:i] isEqualToString:[recipeObject.keywords objectAtIndex:j]]) {
                matchFound = YES;
                break;
            }
        }

        NSMutableAttributedString *attString = 
                [[NSMutableAttributedString alloc] initWithString:[dividesString objectAtIndex:i]];

        if (matchFound) {
            NSLog(@"Found a match");
            // Make the attributed string green
            [attString addAttribute:NSForegroundColorAttributeName 
                value:[UIColor greenColor] 
                range:NSMakeRange(0, attString.length)];   
            // Append the ingredient to listIngreditents
            [listIngredients appendAttributedString:attString];
        }
        else {
            NSLog(@"Match not found");
            // Append the ingredient to listIngreditents
            // with the default color
            [listIngredients appendAttributedString:attString];
        }
    }

    // Set the label, ex. self.recipeIngredients.attributedText = listIngredients;
}

But there's a more simple solution -- I recommend forgoing the inner loop entirely and using containsObject: to see whether the recipeObject.keywords array contains the current ingredient, ex:

- (void)drawTheCell:(Recipe *)recipeObject {

    self.recipeTitle.text = recipeObject.title;

    // Break up the recipe ingredients into components
    NSArray *dividesString = [recipeObject.ingredients componentsSeparatedByString:@", "];

    // Create a mutable attributed string so you can maintain
    // color attributes
    NSMutableAttributedString *listIngredients = [[NSMutableAttributedString alloc] init];

    // Loop through the ingredient components
    for (int i=0; i < dividesString.count; i++) {

        // Add a comma if it's not the first ingredient
        if (i > 0) {
             NSMutableAttributedString *commaString = [[NSMutableAttributedString alloc] initWithString:@", "];
            [listIngredients appendAttributedString:commaString];
        }

        NSMutableAttributedString *attString = 
                [[NSMutableAttributedString alloc] initWithAttributedString:[dividesString objectAtIndex:i]];

        // If recipeObject.keywords contains the current
        // ingredient, add the green attributed string
        if([recipeObject.keywords containsObject:[dividesString objectAtIndex:i]]) {
            NSLog(@"Found a match");
            // Make the attributed string green
            [attString addAttribute:NSForegroundColorAttributeName 
                value:[UIColor greenColor] 
                range:NSMakeRange(0, attString.length)];   
            // Append the ingredient to listIngreditents
            [listIngredients appendAttributedString:attString];
        }
        // Else, simply add the string
        else {
            NSLog(@"Match not found");
            // Append the ingredient to listIngreditents
            // with the default color
            [listIngredients appendAttributedString:attString];
        }
    }

    // Set the label, ex. self.recipeIngredients.attributedText = listIngredients;
}

Upvotes: 1

Fennelouski
Fennelouski

Reputation: 2431

You're on the right track but the one major issue that will prevent you from ever having different words in different colors is that you're not using NSMutableAttributedString. Each time you want to have a word be a different color, you need to add that attribute to just that section of the string.

Once you have your formatted attributed string, you then need to set myTextField.attributedText.

Upvotes: 0

Related Questions