前言
最近项目中需要对UITextView
中输入的文本作行高设置, 本来是个很简单的需求, 最后实现起来却费了好多功夫.
实现思路
以下是我的实现方式, 如果有需要改进的地方, 还请各位指出:
- 每次文本增加时(即不包括删除), 给
UITextView
设置属性文本 - 重置光标位置, 因为上步设置过属性文本后,光标移到最后面
代码
下面的代码可能比较碎, 因为我剥离了一些业务逻辑, 但是不妨碍阅读.
- 设置属性文本
- (void)textViewDidChange:(UITextView *)textView{
[self setAttributedString:textView.text forTextView:textView];
}
1.1 步骤1中的方法:
- (void)setAttributedString:(NSString *)string forTextView:(UITextView *)textView{
if (!isSetAttr_) {
return;
}
///1.设置成富文本
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:[self attributeForTextView]];
textView.attributedText = attrString;
}
1.1.1 步骤1.1中的方法
- (nullable NSDictionary<NSAttributedStringKey, id> *)attributeForTextView{
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 7;
NSDictionary *attr = @{
NSFontAttributeName : [UIFont systemFontOfSize:14],
NSParagraphStyleAttributeName : paragraphStyle
};
return attr;
}
1.1 中的isSetAttr_
的赋值来自这个代理方法:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
因为上述方法调用顺序在
- (void)textViewDidChange:(UITextView *)textView
之前. 从字面就可以理解:
- 前者意思是: 可以替换吗? 如果你回答了可以替换(
return YES
) - 后台意思是: 已经替换了.
- 设置光标位置, 及赋值上述
isSetAttr_
static NSRange lastRange_;
static BOOL isSetAttr_;
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (text.length != 0) { //不是删除文本
textView.selectedRange = NSMakeRange(lastRange_.location+text.length, 0);
}
[self setContentOffsetWithCursorLocation:lastRange_.location textView:textView];
});
lastRange_ = range;
isSetAttr_ = text.length != 0;
return YES;
}
此处有两个细节:
-
text.length == 0
时, 说明用户在删除文本 - 使用
dispatch_after
延迟的原因, 是在stackerflow
上面得到的一个回答. 抱歉链接找不到了. 如果不添加的话, 你就会发现在正常速度文本变化时, 光标位置设置错误.
ps: 就像许多UI的操作一样, 如果你不知道代码哪里出了问题, 可以尝试延迟
最后还有一个小问题, 按照抽取方法的原则. isSetAttr_
不应该在方法内部判断, 应该作为一个标志参数传入方法中.最终效果如下:
网友评论