如何让UIRefreshControl在UICollectionView上方居中?横向滚动偏移问题求解
如何正确将UIRefreshControl居中放置在可滚动的UICollectionView上方?
嘿,这个问题我之前做横向滚动列表的时候也踩过坑!针对你提到的横向滚动UICollectionView时UIRefreshControl偏移、无法保持居中的情况,完全不用每次手动计算中心点,有两种非常标准的解决思路:
方案1:把UIRefreshControl绑定到父视图(推荐)
默认情况下,UIRefreshControl是附加在UICollectionView的内容区域里的,所以横向滚动时会跟着内容一起偏移。换个思路,我们把它加到collectionView的父视图上,用Auto Layout约束让它始终固定在屏幕(或父视图)中心:
// 假设你的collectionView已经添加到当前控制器的view中 let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: #selector(refreshData), for: .valueChanged) view.addSubview(refreshControl) // 设置Auto Layout约束,让控件始终居中 refreshControl.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ refreshControl.centerXAnchor.constraint(equalTo: view.centerXAnchor), refreshControl.topAnchor.constraint(equalTo: collectionView.topAnchor, constant: 16) // 可根据需求调整和collectionView的间距 ])
这么设置后,不管collectionView怎么横向滚动,refreshControl都会牢牢固定在父视图中心,再也不会跟着偏移了。
方案2:监听滚动事件动态修正位置
如果你更倾向于把UIRefreshControl直接挂在collectionView上,可以监听滚动事件,在滚动时自动调整控件的中心位置,让它对齐屏幕中心:
// 先给collectionView绑定refreshControl collectionView.refreshControl = UIRefreshControl() collectionView.refreshControl?.addTarget(self, action: #selector(refreshData), for: .valueChanged) // 遵守UIScrollViewDelegate,实现滚动监听方法 func scrollViewDidScroll(_ scrollView: UIScrollView) { guard let refreshControl = collectionView.refreshControl else { return } // 计算屏幕中心X,结合contentOffset修正位置,让控件保持在视觉中心 let screenCenterX = view.bounds.midX refreshControl.center.x = screenCenterX + scrollView.contentOffset.x }
这个方法会在每次滚动时自动校准位置,不需要你手动计算复杂的偏移逻辑,效果同样稳定。
额外小提示:自定义带图的Refresh Control
如果你的refreshControl里包含自定义图像视图,记得把图像的约束绑定到refreshControl的中心,这样内部元素不会因为控件位置调整而错位:
let customRefreshIcon = UIImageView(image: UIImage(named: "refresh-spinner")) refreshControl.addSubview(customRefreshIcon) customRefreshIcon.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ customRefreshIcon.centerXAnchor.constraint(equalTo: refreshControl.centerXAnchor), customRefreshIcon.centerYAnchor.constraint(equalTo: refreshControl.centerYAnchor) ])
这样整个控件的视觉一致性会更好,滚动时也不会出现图标偏移的问题。
内容的提问来源于stack exchange,提问作者Frederick C. Lee
相关产品推荐
相关产品推荐

