一,3种监听方式
监听 UITextView
的文本发生变化的方法
1,代理
- (void)textViewDidChange:(UITextView *)textView
2,通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChange) name:UITextViewTextDidChangeNotification object:nil];
- (void)didChange{
NSLog(@"noti -- didChange");
}
注意:代理和通知一样,只能够监听到 键盘输入
时的文本变化。- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
方法也只能监听 键盘输入
时的变化 (setText: 方式无法监听)
3,kvo
[self addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if (object == self && [keyPath isEqualToString:@"text"]) {
NSLog(@"text did change -- observeValueForKeyPath");
}
}
注意:kvo 只能够监听到通过 setter
方法设置 textView.text
的时候文本的变化(无法监听键盘编辑)
二,kvo监听的应用
1,监听 textView.text
设置变化并做处理
应用中有时候需要监听文本的变化,同时又有缓存这一功能,使用缓存数据的时候,文本通过 textView.text = @"缓存文本信息"
的方式设置,这个时候,代理和通知都无法监听到这种变化,因此可以通过 kvo 的方式监听这一设置的情况变化。
在 kvo 的监听中,可以完善代理方法和通知无法监听到的文本变化,可以在监听中实现自己的文本变化代理或通知
2,内部设置 text
,kvo 不做处理
在 1,监听
textView.text设置变化
的基础上,对文本输入的内容做处理,如 文本超过固定长度截取后面的内容
过滤文本中的空格
等操作,而这些操作是我们内部实现的,不需要在 kvo 的监听方法中处理,跳出处理
{
BOOL _notObserveTextChanged; // 标识是否 kvo 处理
}
- (void)setTextNoObserve:(NSString *)text{
_notObserveTextChanged = YES;
self.text = text;
_notObserveTextChanged = NO;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if (_notObserveTextChanged) {
return;
}
if (object == self && [keyPath isEqualToString:@"text"]) {
NSLog(@"text did change -- observeValueForKeyPath");
}
}
观察下面方法的调用顺序
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
NSLog(@"shouldChange");
return YES;
}
- (void)textViewDidChange:(UITextView *)textView{
NSLog(@"textViewDidChange");
}
- (void)didChange{
NSLog(@"noti -- didChange");
}
打印信息:
2017-02-09 16:02:46.723 textView[26660:257128] shouldChange
2017-02-09 16:02:46.725 textView[26660:257128] textViewDidChange
2017-02-09 16:02:46.725 textView[26660:257128] noti -- didChange
可以发现,UITextViewTextDidChangeNotification
通知也是在是否允许文本改变之后调用的