最近在做一个富文本编辑器功能,碰到一个问题:textview后面输入的文字他的attribute会和他前一个字符的attr一样。我想让他在中间其他位置编辑的时候会随同前一个字符attr,在text最后面追加编辑的时候是按照默认的字体样式来编辑。
起先刚开始从网络找了一个方法是在UITextview的代理方法shouldChangeTextInRange中来设置你将要输入字符的attribute。然后添加到textview的textStorage中,textStorage是NSMutableAttribute的子类,我们要动态的设置textview的atts可以直接设置textStorage,而不用去重置他的attributedText,这一块我绕了好多弯路。
来看代码实现:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if(![text isNotBlank])//是 nil @"" @" " '\r' 的字符 YYKit的nsstring+yyadd
{
return YES;
}
if(NSMaxRange(range) == textView.textStorage.length)
{
if(textView.textStorage.length == 0)
{
return YES;
}
else
{
UIFont * defaultFont =...默认字体
UIColor * defaultColor = ...默认颜色
__block BOOL isOld = YES;
[textView.textStorage enumerateAttributesInRange:NSMakeRange(textView.textStorage.length - 1, 1) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
if(attrs.allKeys.count > 2)
{
isOld = NO;
*stop = YES;
}
UIFont * fontL = attrs[NSFontAttributeName];
UIColor * colorL = attrs[NSForegroundColorAttributeName];
if(![fontL.fontName isEqualToString:defaultFont.fontName] ||
fontL.pointSize != defaultFont.pointSize ||
![colorL.hexString isEqualToString:defaultColor.hexString])
{
isOld = NO;
*stop = YES;
}
}];
if(!isOld)
{
NSMutableAttributedString * att = [[NSMutableAttributedString alloc] initWithString:text];
[att yh_font:defaultFont];
[att yh_color:defaultColor];
[textView.textStorage insertAttributedString:att atIndex:range.location];
textView.selectedRange = NSMakeRange(range.location+text.length, 0);
return NO;
}
else
{
return YES;
}
}
}
else
{
return YES;
}
}
但是这个代码有个问题,如果是输入中文汉字的话,他是先输入英文字母的然后确认文字选择的,所以汉字的第一输入字符会被直接显示出来。感觉姿势又不对。
看我们简书的app可以编辑的好好的。纠结了很久,不得法 。
后面反反复复看了UITextview的属性和方法找到了typingAttributes
这个属性使用与用户将要输入新的text的时候,这个是给将要输入的text设置了文字的属性,当选择变化的时候,这个字典就会被自动清空。
意思就是给你将要输入的text设置他的attributes。
代码调整一下:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if(NSMaxRange(range) == textView.textStorage.length)
{
if(textView.textStorage.length != 0)
{
UIFont * defaultFont = 默认字体
UIColor * defaultColor =默认颜色
__block BOOL isOld = YES;
[textView.textStorage enumerateAttributesInRange:NSMakeRange(textView.textStorage.length - 1, 1) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
if(attrs.allKeys.count > 2)
{
isOld = NO;
*stop = YES;
}
UIFont * fontL = attrs[NSFontAttributeName];
UIColor * colorL = attrs[NSForegroundColorAttributeName];
if(![fontL.fontName isEqualToString:defaultFont.fontName] ||
fontL.pointSize != defaultFont.pointSize ||
![colorL.hexString isEqualToString:defaultColor.hexString])
{
isOld = NO;
*stop = YES;
}
}];
if(!isOld)
{
self.textV.typingAttributes = @{NSFontAttributeName:defaultFont,NSForegroundColorAttributeName:defaultColor};
}
}
}
return YES;
}
没有问题了 ヽ(゚∀゚)メ(゚∀゚)ノ