【问题标题】:UITextView - Highlight text with NSBackgroundColor - exclude line breaksUITextView - 使用 NSBackgroundColor 突出显示文本 - 排除换行符
【发布时间】:2014-06-03 20:18:46
【问题描述】:

我有一个文本突出显示的工作功能,问题是它还突出显示换行符。看图:

下面是我用来高亮的函数:

   -(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]];
        }
    }

有什么简单的解决办法吗?我应该在换行之前分割字符串并分别突出显示它们吗?另请注意,字符串可由用户编辑,因此必须有一些逻辑来检查文本是否在编辑文本的其他部分时没有中断。

感谢您的任何建议。

【问题讨论】:

  • 尝试设置文本左对齐
  • 对我来说没什么区别。

标签: ios objective-c uitextview textkit


【解决方案1】:

TextViewHighlighter

基本上,我们需要检测换行符的范围,并将它们的属性设置为NSBackgroundColorAttributeName: [UIColor clearColor]

NSMutableAttributedString *highlighedAttributedString = [[NSMutableAttributedString alloc] initWithString:self.text];
    [highlighedAttributedString addAttributes:@{NSForegroundColorAttributeName: self.textColor,
                                                NSBackgroundColorAttributeName: self.highlightedColor
                                                }
                                        range:NSMakeRange(0, self.text.length)];

    for (NSValue *rangeValue in rangeValues) {
        NSRange range = [rangeValue rangeValue];
        [highlighedAttributedString addAttributes:@{NSBackgroundColorAttributeName: [UIColor clearColor],
                                                    }
                                            range:range];
    }

【讨论】:

    【解决方案2】:

    我的解决方案并不简单,不知道能不能解决你所有的问题,但我设法达到了你想要的效果。

    我已经在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 来实现这一点。 (当子字符串变得太长而无法适应线宽时,它变为零)。

    该方法为每一行返回一个范围数组。 (范围转换为NSStrings 和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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 2015-07-12
      • 2018-08-25
      • 2015-04-27
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多