I have a working feature with text highlighting, the problem is that it also highlights line break. See the image:
Below is a function I use for highlighting:
-(void)setHighlight{
//set highlighted
__block BOOL textIsHighlited = YES;
[self.attributedText enumerateAttributesInRange:[self selectedRange] options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
if ([attrs valueForKey:@"NSBackgroundColor"] == Nil) {
textIsHighlited = NO;
}
}];
if (textIsHighlited) {
[self.textStorage removeAttribute:NSBackgroundColorAttributeName range:[self selectedRange]];
}else{
[self.textStorage addAttribute:NSBackgroundColorAttributeName value:[UIColor greenColor] range:[self selectedRange]];
}
}
Is there any simple solution? Should I divide the string before line breaks and highlight them separately? Also note that the strings are editable by user, so there would have to be some logic to check if the text didn't break while editing other part of it.
Thanks for any suggestions.
My solution is not simple and I do not know if it solves all your problems, but I managed to achieve the effect you wanted.
I've tested it on
UILabel
, on different fonts and font sizes, and it worked well.Here what i've done:
The method above splits the
text
string into separate lines. Unfortunately the methodboundingRectWithSize:options:attributes:context:
does not support line break by word wrap, so i had to detect it myself. I achieved that by checking ifsubstringRect.size.width == 0
. (It changes to zero, when substring becomes too long to fit the line width).The method returns an array of ranges for every line. (Ranges are converted to
NSString
s withNSStringFromRange
).Example of use:
See TextViewHighlighter
Basically, we need to detect the ranges of line break characters, and make attributes for them to
NSBackgroundColorAttributeName: [UIColor clearColor]