UITextView - 使用NSBackgroundColor突出显示文本 - 排除换行符 [英] UITextView - Highlight text with NSBackgroundColor - exclude line breaks

查看:133
本文介绍了UITextView - 使用NSBackgroundColor突出显示文本 - 排除换行符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a working feature with text highlighting, the problem is that it also highlights line break. See the image:

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

Below is a function I use for highlighting:

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

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

Is there any simple solution? Should I divide the string before line breaks and highlight them separately? Also note that the strings are editable by user, so there would have to be some logic to check if the text didn't break while editing other part of it.

谢谢任何建议。

推荐答案

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

My solution is not simple and I do not know if it solves all your problems, but I managed to achieve the effect you wanted.

我已经在 UILabel 上测试了它,在不同的字体和字体大小上,它运行良好。

I've tested it on UILabel, on different fonts and font sizes, and it worked well.

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

上面的方法拆分文本字符串分成不同的行。不幸的是,方法 boundingRectWithSize:options:attributes:context:不支持换行换行,所以我必须自己检测它。我通过检查 substringRect.size.width == 0 来实现。
(当子串变得太长而无法适应线宽时,它变为零)。



该方法返回每行的范围数组。 (范围转换为 NSString s, NSStringFromRange )。

The method above splits the text string into separate lines. Unfortunately the method boundingRectWithSize:options:attributes:context: does not support line break by word wrap, so i had to detect it myself. I achieved that by checking if substringRect.size.width == 0. (It changes to zero, when substring becomes too long to fit the line width).

The method returns an array of ranges for every line. (Ranges are converted to NSStrings with 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;
}

这篇关于UITextView - 使用NSBackgroundColor突出显示文本 - 排除换行符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆