我的解决方案并不简单,不知道能不能解决你所有的问题,但我设法达到了你想要的效果。
我已经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:
不支持自动换行,所以我不得不自己检测它。我通过检查 if 实现了这一点substringRect.size.width == 0
。(当子字符串变得太长而无法适应线宽时,它变为零)。
该方法为每一行返回一个范围数组。(范围转换为NSString
s 与NSStringFromRange
)。
使用示例:
- (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;
}