ios - UITextView - 使用 NSBackgroundColor 突出显示文本 - 排除换行符

标签 ios objective-c uitextview textkit

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

enter image description here

下面是我用来突出显示的函数:

   -(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/

相关文章:

objective-c - 不同版本的 Mac OS X 之间的代码分开吗?

objective-c - 再次将 textKit 从 Objective-C 转换为 Swift

iOS - NSNotificationCenter 多个UIKeyboard通知

ios - 使用 Storyboard的 UIPageViewController 示例

ios - 如何使用 VideoCore 创建编码 session ?

iphone - @符号在字符串之前的用途?

xcode - 如何知道何时将文本粘贴到 UITextView 中

ios - 如何更改多个 IBOutlet 的属性

ios - 更改导航栏ios6和ios7的颜色

iphone - 如何解决 Objective C 中函数的警告隐式声明