关于KVO的介绍有很多,我就不多说,下面直接上实现代码:
第一步,将self
添加为观察者,同时也将self
设置为被观察对象,keyPath
设置为self.mainScrollView.contentOffset
,我也不知道context
参数的作用,所以就传了nil
.
[self addObserver:self forKeyPath:@"self.mainScrollView.contentOffset" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
当然,你也可以将self.mainScrollView
设置为被观察对象,self
为观察者,keyPath
设置为contentOffset
.
[self.mainScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
第二步,实现KVO
的方法,如果有多个监听对象,每一个keyPath
一定要和上面的一样
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"contentOffset"])
{
NSValue *oldvalue = change[NSKeyValueChangeOldKey];
NSValue *newvalue = change[NSKeyValueChangeNewKey];
CGFloat oldoffset_y = oldvalue.UIOffsetValue.vertical;
CGFloat newoffset_y = newvalue.UIOffsetValue.vertical;
NSLog(@"Old:%f\nNew:%f",oldoffset_y,newoffset_y);
if (newoffset_y > oldoffset_y)
{
NSLog(@"向下滑动");
}
else if(newoffset_y < oldoffset_y)
{
NSLog(@"向上滑动");
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
通过
NSKeyValueChangeKey
取出的值是NSConcreteValue
类型的,也就是NSValue
,我们可以根据它的UIOffsetValue
属性,来取到我们需要的值。
三,最后一定要在相应的方法中释放掉观察者,keyPath
路径一定要和上面的对应。
- (void)dealloc
{
[self.mainScrollView removeObserver:self forKeyPath:@"contentOffset"];
}
后续补充
关于观察者对象的释放,也可以在viewDidDisappear
中释放
- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[self.mainScrollView removeObserver:self forKeyPath:@"contentOffset"];
}
因为,在很多时候,因为对象引用计数和内存释放的问题,dealloc
不一定执行,所以viewDidDisappear
才能确保观察者对象被移除。