突出显示UILabel中的文本

我正在尝试设置背景颜色/突出显示UILabel的文本。 问题是为了保持文本居中,添加到UILabel换行符和空格也被突出显示。

在此处输入图像描述

注意UILabel最后一行之前的间距是突出显示的。 此外,还突出显示任何新行的开头和结尾。

我正在使用以下代码创建上面的示例:

 -(void)createSomeLabel { // Create and position my label UILabel *someLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width - 40, self.view.frame.size.height - 300)]; someLabel.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2); someLabel.textAlignment = NSTextAlignmentCenter; someLabel.textColor = [UIColor whiteColor]; someLabel.lineBreakMode = NSLineBreakByWordWrapping; someLabel.numberOfLines = 0; [self.view addSubview:someLabel]; // This string will be different lengths all the time NSString *someLongString = @"Here is a really long amount of text that is going to wordwrap/line break and I don't want to highlight the spacing. I want to just highlight the words and a single space before/after the word"; // Create attributed string NSMutableAttributedString *someLongStringAttr=[[NSMutableAttributedString alloc] initWithString:someLongString attributes:nil]; // Apply background color [someLongStringAttr addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithWhite:0 alpha:0.25] range:NSMakeRange(0, someLongStringAttr.length)]; // Set text of label someLabel.attributedText = someLongStringAttr; } 

我想要实现的输出是仅突出文本和单词之间的空格(如果只有一个空格)。 文本的长度和UILabel的大小将不断变化,因此难以编写解决方案的硬编码。

在我看来,换行是问题所在。 我的想法是尝试知道UILabel何时添加换行符,然后从突出显示的字符范围中删除该字符。

看来您不能只询问UILabel换行的位置,但是当您将NSString添加到标签时,可以检查NSString的大小。 使用此信息,您可以不断检查每个角色的高度,并在高度变化时知道您有一个新线。

我做了一个示例,它使用Label的字符串并将其分成将出现在UILabel中的各个行。 一旦我有了每一行,我只需在每一行设置背景颜色而不是整个字符串。 这消除了在换行符上设置的背景颜色。

可能有更好的解决方案,这个可能会针对更好的性能进行优化,但这是一个起点,它似乎有效。

突出显示单词

 - (void)createSomeLabel { // Create and position my label UILabel *someLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width - 40, self.view.frame.size.height - 300)]; someLabel.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2); someLabel.textAlignment = NSTextAlignmentCenter; someLabel.textColor = [UIColor whiteColor]; someLabel.lineBreakMode = NSLineBreakByWordWrapping; someLabel.numberOfLines = 0; [self.view addSubview:someLabel]; // This string will be different lengths all the time NSString *someLongString = @"Here is a really long amount of text that is going to wordwrap/line break and I don't want to highlight the spacing. I want to just highlight the words and a single space before/after the word"; // Create attributed string NSMutableAttributedString *someLongStringAttr=[[NSMutableAttributedString alloc] initWithString:someLongString attributes:nil]; // The idea here is to figure out where the UILabel would automatically make a line break and get each line of text separately. // Temporarily set the label to be that string so that we can guess where the UILabel naturally puts its line breaks. [someLabel setText:someLongString]; // Get an array of each individual line as the UILabel would present it. NSArray *allLines = getLinesForLabel(someLabel); [someLabel setText:@""]; // Loop through each line of text and apply the background color to just the text within that range. // This way, no whitespace / line breaks will be highlighted. __block int startRange = 0; [allLines enumerateObjectsUsingBlock:^(NSString *line, NSUInteger idx, BOOL *stop) { // The end range should be the length of the line, minus one for the whitespace. // If we are on the final line, there are no more line breaks so we use the whole line length. NSUInteger endRange = (idx+1 == allLines.count) ? line.length : line.length-1; // Apply background color [someLongStringAttr addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithWhite:0 alpha:0.25] range:NSMakeRange(startRange, endRange)]; // Update the start range to the next line startRange += line.length; }]; // Set text of label someLabel.attributedText = someLongStringAttr; } #pragma mark - Utility Functions static NSArray *getLinesForLabel(UILabel *label) { // Get the text from the label NSString *labelText = label.text; // Create an array to hold the lines of text NSMutableArray *allLines = [NSMutableArray array]; while (YES) { // Get the length of the current line of text int length = getLengthOfTextInFrame(label, labelText) + 1; // Add this line of text to the array [allLines addObject:[labelText substringToIndex:length]]; // Adjust the label text labelText = [labelText substringFromIndex:length]; // Check for the final line if(labelText.length 

我遇到了同样的问题,发现没有巨大的性能成本的解决方案。 您只需将TTTAttributedLabel添加到项目中即可。

我的问题演示项目:

 #import "TTTAttributedLabel.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UILabel *label1 = [UILabel new]; label1.textAlignment = NSTextAlignmentCenter; label1.numberOfLines = 0; label1.frame = CGRectMake(20, 0, CGRectGetWidth(self.view.frame) - 40, CGRectGetHeight(self.view.frame) / 2.0); [self.view addSubview:label1]; TTTAttributedLabel *label2 = [TTTAttributedLabel new]; label2.textAlignment = NSTextAlignmentCenter; label2.numberOfLines = 0; label2.frame = CGRectMake(20, CGRectGetHeight(self.view.frame) / 2.0, CGRectGetWidth(self.view.frame) - 40, CGRectGetHeight(self.view.frame) / 2.0); [self.view addSubview:label2]; NSDictionary *attributes = @{NSBackgroundColorAttributeName:[UIColor blackColor], NSForegroundColorAttributeName:[UIColor whiteColor], NSFontAttributeName:[UIFont systemFontOfSize:32 weight:UIFontWeightBold]}; NSAttributedString *string = [[NSAttributedString alloc] initWithString:@"Some very long string which can contain newlines and some other stuff" attributes:attributes]; label1.attributedText = string; label2.text = string; } @end 

在此处输入图像描述

从iOS 10.3开始,相同的代码现在可以产生所需的结果。 不确定这是一个错误还是一个新function。

 -(void)createSomeLabel { // Create and position my label UILabel *someLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width - 40.0, self.view.frame.size.height - 300.0)]; someLabel.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0); someLabel.textAlignment = NSTextAlignmentCenter; someLabel.textColor = [UIColor whiteColor]; someLabel.lineBreakMode = NSLineBreakByWordWrapping; someLabel.numberOfLines = 0; [self.view addSubview:someLabel]; // This string will be different lengths all the time NSString *someLongString = @"Here is a really long amount of text that is going to wordwrap/line break and I don't want to highlight the spacing. I want to just highlight the words and a single space before/after the word"; // Create attributed string NSMutableAttributedString *someLongStringAttr = [[NSMutableAttributedString alloc] initWithString:someLongString attributes:nil]; // Apply background color [someLongStringAttr addAttribute:NSBackgroundColorAttributeName value:[UIColor colorWithWhite:0 alpha:0.25] range:NSMakeRange(0, someLongStringAttr.length)]; // Set text of label someLabel.attributedText = someLongStringAttr; } 

在此处输入图像描述