CollectionViewCell 滚动到错误的位置

Posted

技术标签:

【中文标题】CollectionViewCell 滚动到错误的位置【英文标题】:CollectionViewCell scrolls to wrong position 【发布时间】:2020-06-06 17:16:29 【问题描述】:

我有一个collectionView,它固定在视图的最前面(如第一张照片所示),它有isPagingEnabled = true。我还隐藏了导航栏。

当 cv 首次加载时,单元格错误地显示在设备的顶部下方(如第二张照片所示)。

当我滚动/翻页时,单元格在凹槽后面正确显示(第三张照片)。

如果我向上滚动/翻页到第一个单元格,它会正确定位自己(第三张照片)。但是,如果我随后将 cv 拉下,则单元格会弹回不正确的位置(第二张照片)。

我还注意到单元格的位置错误,如果我点击它,它会自动滚动到正确的位置。

我试过这个answer 和这个answer 都没有成功。我在函数中调用了view.layoutIfNeeded()collectionView.layoutIfNeeded()

为什么当 cv 首次加载和我拉动刷新时单元格显示不正确,但当我向上或向下翻页时它显示正确?

lazy var collectionView: UICollectionView  = 

    let layout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.alwaysBounceVertical = true
    collectionView.showsVerticalScrollIndicator = false
    collectionView.backgroundColor = .white
    collectionView.register(HomeCell.self, forCellWithReuseIdentifier: homeCell)

    collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    collectionView.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    collectionView.isPagingEnabled = true

    return collectionView
()

override func viewDidLoad() 
    super.viewDidLoad()
    view.backgroundColor = .white

    setCollectionViewAnchors()


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
    navigationController?.setNavigationBarHidden(true, animated: false)


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

    let width = collectionView.frame.width
    let height = collectionView.frame.height

    return CGSize(width: width, height: height)


func setCollectionViewAnchors() 

    let homeIndicatorHeight: CGFloat = 34 // https://***.com/a/56639186/4833705

    view.addSubview(collectionView)

    collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
    collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
    collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -homeIndicatorHeight).isActive = true

第一张照片,简历锚点,顶部固定在缺口后面视图的最顶部。

第二张照片,单元格第一次在槽口后面显示不正确,当在第一张单元格时,拉下 cv 时显示不正确。

第三张照片,滚动/分页时单元格在凹槽后面正确显示

【问题讨论】:

【参考方案1】:

尝试在viewWillAppear()方法中调用layoutIfNeeded(),像这样:

override func viewWillAppear(_ animated: Bool) 
   super.viewWillAppear(animated)
   navigationController?.setNavigationBarHidden(true, animated: false)
   self.view.layoutIfNeeded()

【讨论】:

不能在带刘海屏的 iPhone 上使用,谢谢尝试 尝试在viewDidAppear() 中调用layoutIfNeeded()。有时会有所帮助 在那里也不起作用。它在其中任何一个中都不起作用,因为即使在这些方法运行之后也会出现问题。不过谢谢:)【参考方案2】:

我找到了answer here。

我必须将此行添加到我的 collectionView 中:

collectionView.contentInsetAdjustmentBehavior = .never

【讨论】:

更新我还必须添加这一行,因为在滚动回同一个单元格后未调用 cellForItem 时发生了一些奇怪的行为:collectionView.isPrefetchingEnabled = false跨度>

以上是关于CollectionViewCell 滚动到错误的位置的主要内容,如果未能解决你的问题,请参考以下文章

如何将imageView添加到collectionViewCell中的scrollView

将 UIScrollView 放在 CollectionViewCell 上,但滚动视图无法滚动

向上向下滚动时,collectionViewCell 图像发生变化

滚动后 UICollectionViewCells 子视图呈现错误

我可以在 1 UICollectionView 中使用 collectionViewCell 2 Cell 吗?

如何判断 CollectionViewCell 是不是位于屏幕中心