swift - UICollectionViewCells 在重新排列后重置其大小

标签 swift ios8 uicollectionview uicollectionviewcell uicollectionviewlayout

我有一个带有标签的单元格的 UICollectionView,我希望能够通过拖放对它们重新排序。

单元格的大小是用 estimatedItemSize 设置的,因为我希望它们的大小各不相同,具体取决于单元格中文本的大小。我可以让它看起来很好。但是,一旦我使用 collectionView.moveItemAtIndexPath,单元格似乎会采用默认大小。

在移动后立即重置 collectionView 的流布局也不能解决问题。

viewDidLoad

    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.estimatedItemSize = CGSize(width: 100, height: 100)
    collectionView.collectionViewLayout = layout

重新排列文本的 UIPanGestureRecognizer

func handlePan(sender: UIPanGestureRecognizer) {
    let locationPoint = sender.locationInView(collectionView)
    if sender.state == UIGestureRecognizerState.Began {

        if let indexPath = collectionView.indexPathForItemAtPoint(locationPoint)? {

            if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
                UIGraphicsBeginImageContext(cell.bounds.size)
                cell.layer.renderInContext(UIGraphicsGetCurrentContext())
                let cellImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()

                movingCellImage = UIImageView(image: cellImage)
                movingCellImage.center = locationPoint
                movingCellImage.transform = CGAffineTransformMakeScale(2, 2)
                collectionView.addSubview(movingCellImage)
                cell.alpha = 0
                movingCellOriginalIndexPath = indexPath

            }

        }

    } else if sender.state == UIGestureRecognizerState.Changed {
        movingCellImage.center = locationPoint

    } else if sender.state == UIGestureRecognizerState.Ended {

        if let indexPath = collectionView.indexPathForItemAtPoint(locationPoint)? {

            let cell = collectionView.cellForItemAtIndexPath(movingCellOriginalIndexPath)
            collectionView.moveItemAtIndexPath(movingCellOriginalIndexPath, toIndexPath: indexPath)
            cell?.alpha = 1

        }

        movingCellImage.removeFromSuperview()
    }
}

Before and after moving a UICollectionViewCell, having moved the second cell to the first

最佳答案

重新加载动画似乎可以解决问题。
但是之前的布局会保留片刻...您可能需要创建自定义 UICollectionViewLayout 而不是使用 estimatedSize

if let indexPath = collectionView.indexPathForItemAtPoint(locationPoint)? {
    let cell = collectionView.cellForItemAtIndexPath(movingCellOriginalIndexPath)
    collectionView.moveItemAtIndexPath(movingCellOriginalIndexPath, toIndexPath: indexPath)
    cell?.alpha = 1

    collectionView.reloadSections(NSIndexSet(index: 0)) // not reloadData
}

[更新]

正如您所指出的,关键是 -collectionView:layout:sizeForItemAtIndexPath:

  • 不要将 estimatedSize 设置为 UICollectionViewFlowLayout
  • 在上面的委托(delegate)方法中计算每个单元格的大小

像这样:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    let str = data[indexPath.item] // string to show in label

    // calculate size. you can use -boundingRectWithSize: as well
    var txtsize = (str as NSString).sizeWithAttributes([ NSFontAttributeName : UIFont.systemFontOfSize(16)]) // specify label's font
    txtsize.width += 10 // add margin if necessary
    txtsize.height = 100 // calculated text height or any value you want

    return txtsize
}

关于swift - UICollectionViewCells 在重新排列后重置其大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27743881/

相关文章:

ios - 在iOS 8中禁用UIViewController的旋转

ios - 必须调用父类(super class) 'UICollectionView' 的指定初始化程序

ios - 如何使用附加参数在 SWIFT 中制作自定义 MKPolyline - 颜色

swift - 删除隐藏 View / subview 以解冻主视图

ios - 在自定义键盘扩展中播放标准 iOS 键盘点击声音

xcode - NSFetchRequest 返回的 AnyObject 数组在 XCTestCase 中的 Swift XCode 6 Beta 4 中转换时出现 "Swift dynamic cast failed"错误

swift - 如何从 Collection View 中删除项目?

ios - UIView 在滚动时从 UICollectionView 的底部分离

ios - 如何在 stackView 中定位 imageView 和标签,使我能够根据它们的状态调整它们的大小?

ios - 实例成员不能用于类 NSObject 的类型