swift - 如何同时更新 UICollectionViewCell 的边框并执行 UICollectionView Cells 的批量更新

标签 swift uicollectionview uicollectionviewcell performbatchupdates

我的目标是在 UICollectionView 单元格的边框周围添加阴影,同时执行 UICollectionView 的批量更新,这将导致所选单元格的高度扩展。这个想法是,边框周围的阴影将淡入视野,或者像此 GIF 中那样立即进入视野,但会随着细胞生长的实际大小而变化。如代码所示,我特别希望阴影位于单元格周围而不是单元格本身内 - 这是为了保持正确的边界。

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if weekTasks[indexPath.section].count == 0 {
        let emptyCell = collectionView.dequeueReusableCell(withReuseIdentifier: "emptyCellID", for: indexPath) as! EmptyCell
        return emptyCell
    } else {
        let assignmentCell = collectionView.dequeueReusableCell(withReuseIdentifier: "assignCellID", for: indexPath) as! AssignmentCell
        assignmentCell.myAssignment = weekTasks[indexPath.section][indexPath.item]
        assignmentCell.contentView.backgroundColor = UIColor.white
        return assignmentCell
    }
}

// Sets up size of cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    if weekTasks[indexPath.section].count == 0 {
        return CGSize(width: screenWidth, height: 36 )
    } else if (collectionView.indexPathsForSelectedItems?.contains(indexPath))! {
        return CGSize(width: screenWidth, height: 110)
    } else {
        return CGSize(width: screenWidth, height: 46)
    }
}

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.contentView.layer.cornerRadius = 12
    cell?.contentView.layer.masksToBounds = true;
    cell?.contentView.backgroundColor = UIColor.white

    cell?.layer.shadowOffset = CGSize(width: 0 ,height: 1)
    cell?.layer.shadowRadius = 4
    cell?.layer.shadowOpacity = 0.2

    collectionView.performBatchUpdates(nil, completion: { done in
        if done {
            print("Sweet")
        }}
    )
}

override func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.contentView.layer.cornerRadius = 0
    cell?.contentView.layer.masksToBounds = true;

    cell?.layer.shadowOpacity = 0
}

我的收藏 View 单元格

class AssignmentCell: UICollectionViewCell, UIGestureRecognizerDelegate {
var heightConstraint: NSLayoutConstraint?

override init(frame: CGRect) {
    super.init(frame: frame)
    setupViews()
}

let helperView = UIView()

func setupViews() {

    self.contentView.addSubview(helperView)
    let topConstraint = NSLayoutConstraint(item: helperView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0)
    let leftConstraint = NSLayoutConstraint(item: helperView, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 0)
    let rightConstraint = NSLayoutConstraint(item: helperView, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.right, multiplier: 1, constant: 0)
    let bottomConstraint = NSLayoutConstraint(item: helperView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: superview, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0)
    let heightConstraint = helperView.heightAnchor.constraint(equalToConstant: self.frame.height)
    helperView.addConstraints([topConstraint, leftConstraint, rightConstraint, heightConstraint])

    helperView.addSubview(titleView)
    titleView.frame = CGRect(x: 48, y: (self.frame.height / 2) - 10, width: screenWidth - 190, height: 20)

    helperView.addSubview(checkboxView)
    checkboxView.frame = CGRect(x: 10, y: (self.frame.height / 2) - 9, width: 18, height: 18)
}

func expandCell(to height: CGFloat) {
    heightConstraint?.constant = 110

    UIView.animate(withDuration: 0.3, animations: {
        self.layoutIfNeeded()
    }) { (completed) in
    }
}

}

enter image description here

最佳答案

它实际上遵循单元格大小。您之所以会得到这种效果,是因为您设置了固定的单元格高度并在之后对布局更改进行动画处理。您可以尝试自动设置单元格大小(仅适用于展开的单元格大小)。

在您的单元格中,创建一个方法,将尺寸从当前值动画化为 x(在您的情况下为 110)。

添加一个等于容器高度的约束并执行如下操作:

func expandCell(to height: CGFloat) {
    self.cellHeightConstraint?.constant = height

    UIView.animate(withDuration: 0.3, animations: {
        self.layoutIfNeeded()
    }) { (completed) in
    }
}

//编辑

在您的 ContentView 中添加一个新的 UIView,并在其中放置所有其他 View 。将该 View 的顶部、底部、左侧、右侧设置为 0,为其 superview(contentView) 并以 @999 优先级对该 View 设置高度约束。见下图:

enter image description here

关于swift - 如何同时更新 UICollectionViewCell 的边框并执行 UICollectionView Cells 的批量更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53369424/

相关文章:

ios - 如何为单元测试创​​建虚假的 Realm 结果

ios - Swift 4.2 使用 UICollectionViewCell 添加/删除按钮

swift - 在呈现和关闭模态视图 Controller 时如何保持 Collection View 单元格被选中?

ios - 如何在 Swift 中限制文本字段中的数字?

ios - Swift Parse 查询表

uiviewcontroller - UICollectionViewDelegate 的奇怪行为

ios - 以编程方式更改 Collection View 单元格中标签的字体

swift - 在表格 View 单元格中重新加载数据收集 View (Swift)

xcode - 无法转换类型 'UICollectionViewCell' 的值

ios - iOS 9 中是否有用于 3d touch 的公共(public) API?