今天测试提了一个bug,说点击下一题的时候,界面没有刷新题目,还在老题目那里,我说不可能啊,我这边好好的,后来一看,她的机子是iOS 14的,我说那我适配一下好了。
我的界面层级是一个大的collectionView
占据页面,里面的cell的大小跟collectionview
的bounds
一样大。
下面是我的collectionview创建代码
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: SCREEN_WIDTH, height: SCREEN_HEIGHT - NavigationContentTop - SafeAreaInsetsConstantForDeviceWithNotch.bottom - 60)
layout.sectionInset = UIEdgeInsets.zero
layout.scrollDirection = .horizontal
let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
collectionView.xh_register(XHOEWebParentCollectionViewCell.self)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.backgroundColor = .clear
collectionView.showsHorizontalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.isScrollEnabled = false
if #available(iOS 11.0, *) {
collectionView.contentInsetAdjustmentBehavior = .never
} else {
self.automaticallyAdjustsScrollViewInsets = false
}
return collectionView
}()
我滚动页面调用的代码
self.collectionView.scrollToItem(at: IndexPath(item: collectionViewIndex, section: 0), at: .right, animated: true)
结果找了半天原因没找到,因为看起来很正常,查阅网上的资料,发现调用无效大多是在collectionView
尚未布局的时候就调用了scrollToItem(at: _, at: _, animated: _),跟我的情况不符合
后来想着先用setContentOffset(_, animated: _)试试,后来发现确实可以,但是滚动的页数越多,发现cell偏移也越厉害,查看View hierarchy,发现是cell之间有10的间距,应该是没有设置flowLayout
的minimumLineSpacing属性。调整为0后,重新运行,正常了
但是按理来说没有设置minimumLineSpacing不该影响collectionView
的跳转才对,于是继续检查collectionView
的设置,发现一句可能会影响的代码
collectionView.isPagingEnabled = true
我们查看isPagingEnabled的文档
Discussion
If the value of this property is true, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is false.
文档中解释说scroll view会停止在scroll view的bounds的整数倍的位置
那么如果没有设置minimumLineSpacing(这里我的collectionView
是水平滚动的,所以应该只用设置这个属性就可以了),那么collectionView
在通过scrollToItem(at: _, at: _, animated: _)
滚动到指定页的时候,实际上并没有滚动整数倍的scroll view’s bounds ,和isPagingEnabled属性相违背,所以说到这里,这个bug其实有两个解决方式
- collectionView.isPagingEnabled = false
- 设置minimumLineSpacing为0即可
我把minimumLineSpacing的设置取消掉,单改为isPagingEnabled = false
,测试通过,说明推论是应该正确的。
2020.11.16 更新
最新发现在iPad上有collectionview
在设置了minimumLineSpacing = 0
后调用scrollToItem(at: _, at: _, animated: _)仍然无效,建议设置了collectionView.isPagingEnabled = true
的改用setContentOffset
进行跳转。