iOS填坑之路-UIScrollView中contentOffset的Bug

事情的经过是这样的,项目的主页是一个由一个xib定义的scrollView,设置的contentSize是屏幕宽度的1.75倍,一共分三屏。

这样的布局设计在很多应用中应该是很常见的,并且从业务需求的角度往往需要在scrollView的delegate中根据scrollView的滑动状态和contentOffset做一些切换和调整。那么问题就来了!!!

源代码是这样的

1
2
3
4
5
6
7
8
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if(_scrollView.contentOffset.x > 0){
//do something
if (_scrollView.contentOffset.x > kScreenWidth) {
//代表scrollView进入了第三屏,需要做某些事情
}
}
}

但是这块业务在之后的测试中出现了一个很难复现的Bug。
那就是当滑动到中间屏幕(即contentOffset.x = kScreenWidth的时候),居然进入了>kScreenWidth的判断。
然后进入调试模式,居然发现此时的contentOffset = 321…..
321…..
坑爹么!这是!
于是就这么偶然地发现了这个惊天大坑!
在经过一系列的滑动之后,scrollView会出现contentOffset计算不准确的计算,这也就意味着在做一些针对contentOffset的判断的时候,用==的操作很容易出现问题。

那么解决方案就来了
把if里面的判断改成

1
fabs(_scrollView.contentOffset.x - 1.75 * kScreenWidth) <= 2.0

通过绝对值的模糊判断,解决了原先contentOffset计算不精确所导致的问题。

这也提醒了我,在程序中一些设计浮点数判断相等的时候,需要考虑到计算误差的情况。

当然,不管是此处的bug是因为通过autolayout来控制scrollView的contentOffset也好,还是本身scrollView的一个bug也好,反正这次踩过了坑,以后也就不会再踩了。