使用全宽和动态高度单元格重新排序 UICollectionView 时的 UI 问题

Posted

技术标签:

【中文标题】使用全宽和动态高度单元格重新排序 UICollectionView 时的 UI 问题【英文标题】:UI-Issues while reordering UICollectionView with full-width and dynamic height cells 【发布时间】:2018-08-24 09:55:06 【问题描述】:

我有一个 CollectionView,其中的单元格具有全宽和动态(自动布局计算)高度。

我通过设置估计高度来做到这一点:

flowLayout.estimatedItemSize = CGSize(width: 200, height: 10)

然后在委托方法中返回全宽和任意高度。

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: collectionView.bounds.width, height: 10)

然后在单元格中执行以下操作:

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes 
    setNeedsLayout()
    layoutIfNeeded()
    let size = self.systemLayoutSizeFitting(layoutAttributes.size)

    var newFrame = layoutAttributes.frame
    // note: don't change the width
    newFrame.size.height = ceil(size.height)
    layoutAttributes.frame = newFrame

    return layoutAttributes

一切都按预期工作......单元格大小应有尽有!太好了!

现在我想添加重新排序... 我添加了一个 GestureRecognizer 并让它重新排列我的单元格..

@objc func handleLongPress(gestureRecognizer: UILongPressGestureRecognizer) 

    guard let view = gestureRecognizer.view else  return 
    let location = gestureRecognizer.location(in: view)

    switch gestureRecognizer.state 
    case .began:
        guard let selectedIndexPath = collectionView.indexPathForItem(at: location) else  break 
        collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
    case .changed:
        collectionView.updateInteractiveMovementTargetPosition(location)
    case .ended:
        collectionView.endInteractiveMovement()
    default:
        collectionView.cancelInteractiveMovement()
    

这也基本上可以工作...但是在重新排序期间,我的单元格的动画很奇怪...单元格有时会减小到我的 10 大小,但不会让单元格自行测量。松开拖动后,它又可以工作了……

我注意到,当我缓存我的 CollectionViewCells 的高度时,它会好一些,但对于我以前从未见过的所有单元格,它将再次成为 10 点高的单元格。

为了在重新排序期间使单元格大小正确,我缺少什么?

我也有一个解决这个问题的示例项目,可以在这里找到:https://www.dropbox.com/s/ya6zald4wa6kg10/CollectionViewTester.zip?dl=0

【问题讨论】:

【参考方案1】:

问题是,当重新排序自动调整大小的单元格时,单元格大小会更改为estimatedItemSize

报告了一个开放的雷达here。

【讨论】:

好吧...所以基本上这是一个苹果的错误,不是我的...我已经通过使用 ios11 的新拖放 API 解决了这个问题...他们也有一些问题(我已经提交了错误报告)......但不是那么明显:) @Georg,另一种解决方法是为每个项目设置正确和预先计算的estimatedHeight。但是在多行textViews和标签的情况下,以及其他依赖字体的UIElements,就不方便了。

以上是关于使用全宽和动态高度单元格重新排序 UICollectionView 时的 UI 问题的主要内容,如果未能解决你的问题,请参考以下文章

计算 iOS 中水平 UICollectionView 的动态单元格高度

具有动态高度和半宽的 UICollectionview 单元格

UITableViewAutomaticDimension 打破约束?

Swift - TableViewCell 中不同大小的图像的困难

iOS8“现在”改变动态单元格的高度,重新内部单元格内容

显示更多按钮操作的动态标签和单元格高度