我在Stack Overflow上搜索过很多但我无法找到解决方案。也许我只是误解了一些答案。
我创建了一个UITextView
,我正在使用NSAttributedStrings
来处理UITextView,这很好。
现在,在添加自定义属性后,我被卡住了。
我可以在哪里抓取以在UITextView
内呈现我的自定义属性?是否有委托方法,或者我是否必须创建自己的UITextView
并覆盖方法?
答案 0 :(得分:5)
您可以自定义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'有一个红色的圆形背景。
答案 1 :(得分:-1)
请参阅此简单的代码段,将属性字符串设置为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;
希望这有帮助。
答案 2 :(得分:-1)
如果您要为特定attributes
而不是字符串应用特定textView
,那么您应该继承UITextView
并制作自定义initmethod
或某些返回UITextView
的方法具有指定属性的对象!!如果属性发生变化,您也可以将custom attributes
作为参数传递给方法,我的意思是不修复。如果属性隐式保持相同,则默认设置该类中的属性。