我有一个文本突出显示的工作功能,问题是它也突出了换行符。看图:
下面是我用来突出显示的函数:
-(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]];
}
}
有什么简单的解决方法吗?我应该在换行符之前划分字符串并分别突出显示它们吗?另请注意,字符串可由用户编辑,因此必须有一些逻辑来检查在编辑文本的其他部分时文本是否没有中断。
感谢您的任何建议。
最佳答案
我的解决方案并不简单,不知道是否能解决你所有的问题,但我还是达到了你想要的效果。
我已经在 UILabel
上用不同的字体和字体大小对其进行了测试,效果很好。
这是我所做的:
- (NSArray*)getRangesOfLinesForText:(NSString*)text font:(UIFont*)font containerWidth:(float)width {
NSMutableArray *ranges = [[NSMutableArray alloc] init];
NSInteger lastWhiteSpaceIndex = 0;
NSInteger rangeStart = 0;
NSMutableString *substring = [[NSMutableString alloc] init];
for (int i = 0; i < [text length]; i++) {
char c = [text characterAtIndex:i];
[substring appendFormat:@"%c",c];
CGRect substringRect = [substring boundingRectWithSize:CGSizeMake(width, font.capHeight)options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil];
if([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:c]) {
lastWhiteSpaceIndex = i;
}
if(substringRect.size.width == 0) {
NSRange range;
if (lastWhiteSpaceIndex != i) {
range = NSMakeRange(rangeStart, lastWhiteSpaceIndex-rangeStart);
[ranges addObject:NSStringFromRange(range)];
substring = [[NSMutableString alloc] init];
i = lastWhiteSpaceIndex;
rangeStart = lastWhiteSpaceIndex+1;
}
}
}
//Last Line
NSRange range = NSMakeRange(rangeStart, [text length]-rangeStart);
[ranges addObject:NSStringFromRange(range)];
return ranges;
}
上述方法将 text
字符串拆分为单独的行。不幸的是,方法 boundingRectWithSize:options:attributes:context:
不支持自动换行,所以我不得不自己检测。我通过检查 substringRect.size.width == 0
来实现这一点。
(当子字符串变得太长而无法适应线宽时,它变为零)。
该方法为每一行返回一个范围数组。 (使用 NSStringFromRange
将范围转换为 NSString
)。
使用示例:
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectFromString(@"{{0,0},{300,400}}")];
textLabel.numberOfLines = 0;
[self.view addSubview:textLabel];
NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec luctus quis sapien a rutrum. Vivamus nec leo suscipit nibh rutrum dignissim at vel justo. Maecenas mi orci, ultrices non luctus nec, aliquet et nunc.";
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:text];
for (NSString* stringRange in [self getRangesOfLinesForText:text font:textLabel.font containerWidth:textLabel.frame.size.width]) {
[string addAttribute:NSBackgroundColorAttributeName value:[UIColor greenColor] range:NSRangeFromString(stringRange)];
}
textLabel.attributedText = string;
}
关于ios - UITextView - 使用 NSBackgroundColor 突出显示文本 - 排除换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23169082/