繁体   English   中英

UITextView,NSAttributedString和自定义属性

[英]UITextView, NSAttributedString and custom attributes

我在Stack Overflow上搜索了很多,但是我找不到解决方案。 也许我只是误解了一些答案。

我创建了一个UITextView ,我正在使用NSAttributedStrings来处理UITextView,这很好。

现在,添加自定义属性后,我被卡住了。

在哪里可以挂钩以在UITextView呈现我的自定义属性? 是否有委托方法,还是我必须创建自己的UITextView并覆盖方法?

您可以自定义NSLayoutManager ,并实现它的-drawGlyphsForGlyphRange:atPoint:方法。

例如,您需要具有圆角半径的自定义背景

textView init:

NSTextStorage *textStorage = [NSTextStorage new];
CustomLayoutManager *layoutManager = [[CustomLayoutManager alloc] init];
CGSize containerSize = CGSizeMake(self.view.bounds.size.width,  CGFLOAT_MAX);
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:containerSize];

textContainer.widthTracksTextView = YES;
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];

self.textView = [[UITextView alloc] initWithFrame:yourFrame textContainer:textContainer];

并应用您的自定义属性:

NSMutableAttributedString *mAttrStr = [[NSMutableAttributedString alloc] initWithString:@"SampleText"];
[mAttrStr addAttribute:YourCustomAttributeName value:[UIColor redColor] range:NSMakeRange(0, mAttrStr.length)];  //for example, you want a custom background with a corner radius
[self.textView.textStorage appendAttributedString:mAttrStr];

在CustomLayoutManager.m中

-(void)drawGlyphsForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin {
    NSRange range = [self characterRangeForGlyphRange:glyphsToShow
                                 actualGlyphRange:NULL];
    //enumerate custom attribute in the range
    [self.textStorage enumerateAttribute:YourCustomAttributeName inRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {
        if (value) {
            UIColor *color = value; //the color set above

            NSRange glyphRange = [self glyphRangeForCharacterRange:range
                                          actualCharacterRange:NULL];
            NSTextContainer *container = [self textContainerForGlyphAtIndex:glyphRange.location
                                        effectiveRange:NULL];

            //draw background
            CGContextRef context = UIGraphicsGetCurrentContext();
            CGContextSaveGState(context);
            CGContextTranslateCTM(context, origin.x, origin.y);
            [color setFill];
            CGRect rect = [self boundingRectForGlyphRange:glyphRange inTextContainer:container];

            //UIBezierPath with rounded
            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:100];
            [path fill];
            CGContextRestoreGState(context);
            //end draw

            [super drawGlyphsForGlyphRange:range atPoint:origin];
        }
        else {
            [super drawGlyphsForGlyphRange:range atPoint:origin];
        }

    }];
}

现在'SampleText'有一个红色的圆形背景。

请参阅此简单的代码段,将属性字符串设置为textview

    let attributedString = NSMutableAttributedString(string:"Test string to add attributes")
    attributedString.addAttributes([NSForegroundColorAttributeName:UIColor.greenColor()], range: NSMakeRange(0, attributedString.string.characters.count))
    textView.attributedText = attributedString

对于Objective-C

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:@"Test string to add attributes"];
[attributedString addAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]} range:NSMakeRange(0, attributedString.string.length)];
textView.attributedText = attributedString;

希望这可以帮助。

如果你想为特定的textView而不是string应用特定attributes ,那么你应该initmethod UITextView并使自定义initmethod或某些方法返回具有指定属性的UITextView对象! 如果属性更改,您也可以将custom attributes作为参数传递给方法,我的意思是不修复。 如果属性将隐式保持相同,则默认情况下在该类中设置属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM