滑动单元格时 clipToBounds 不起作用

clipToBounds doesn't work when swiping cells

我有一个默认隐藏多个标签的自定义单元格(用户单击单元格时会看到所有内容)。我正在更改单元格的高度和 cell.clipToBounds = true 以隐藏标签。但这不适用于可编辑的单元格。当我开始向左滑动单元格时,隐藏的内容就会出现。我注意到,如果我首先展开单元格、折叠和滑动,它会起作用,但如果我滑动另一个单元格,它就会停止工作。 有什么建议如何在滑动单元格时隐藏它?

将标签添加到数组。

hidden设置为true:

let labels = [firstLabel, secondLabel, etc.…]
for label in labels {
    label.hidden = true
}

尝试将 contentView clipsToBounds 属性 设置为 true。 通常你不应该把单元格当作视图。

Swift

cell.contentView.clipsToBounds = true

Obj-C

cell.contentView.clipsToBounds = YES

我认为这是在动画和编辑过程中 setEditing 覆盖或忽略 clipsToBounds 的错误。

解决方法:

当 table 为 "closed" 时,您应该隐藏所有不应出现的元素,并在 table 展开时取消隐藏它们。

1) 创建一个 UITableViewCell 方法来 hide/unhide 您需要的所有元素:

func hideAll(hide: Bool) {
        myLabel.hidden = hide
        myUISwitch.hidden = hide
}

2) 初始化单元格时调用上述方法。通常会在单元格内的某处调用,在初始化程序上调用,或者在 cellForRowAtIndexPath 上调用。我检查 cell.bounds.height 以确定单元格是否展开:

//cell init code

//I'm calling this method from inside the cell, so I use self here.
//If you're calling this method from your controller you should
//target the cell with cell.bounds.height, as well as targeting the
//cell to call the method: cell.hideAll(Bool)
var hidden = (self.bounds.height < 80) //change this number depending on your collapsed and expanded cell heights
hideAll(hidden)

3) 此时(如果上述方法是在 cellForRowAtIndexPath 内部或在单元初始值设定项上调用的)您的方法将在创建单元时以及每次单元 展开时调用。但不是在细胞收缩时(更多内容在后面)。所以在你的 editingStyleForRowAtIndexPath:

中添加一些代码
override func tableView(tableView: UITableView,
        editingStyleForRowAtIndexPath indexPath: NSIndexPath)
        -> UITableViewCellEditingStyle{
            if let cell = tableView.cellForRowAtIndexPath(indexPath) as? CustomTableViewCell {
                cell.hideAll(cell.bounds.height < 80) //calls hideAll with a Bool argument, depending on height of cell
            }
            return .Delete
    }

editingStyleForRowAtIndexPath 仅在您滑动的单元格上调用,不会调用任何委托方法,例如 heightForRowAtIndexPath,因此我相信这是隐藏视图项的最佳位置.

好的,这就是解决方案。现在是为什么:

当您想要隐藏这些单元格时,真正的问题是何时隐藏它们。首先,您必须了解 swift 与 tableViewCell 经历的循环。

我假设您是 expanding/contracting heightForRowAtIndexPath 上的单元格。这在语义上是完全有意义的。但假设您有 3 个单元格(全部可扩展)。每当调用 cellForRowAtIndexPathdidSelectRowAtIndexPathheightForRowAtIndexPath 时,我都会执行 println()。在下面的示例中,我点击了第一行,然后是第二行,然后是第三行。在控制台观察结果:

>>>> called didSelectRow at index 0
???? called heightForRow at index 0
???? called heightForRow at index 1
???? called heightForRow at index 2
???? called heightForRow at index 0
==== called cellForRow at index 0
???? called heightForRow at index 0

>>>> called didSelectRow at index 1
???? called heightForRow at index 0
???? called heightForRow at index 1
???? called heightForRow at index 2
???? called heightForRow at index 1
==== called cellForRow at index 1
???? called heightForRow at index 1

>>>> called didSelectRow at index 2
???? called heightForRow at index 0
???? called heightForRow at index 1
???? called heightForRow at index 2
???? called heightForRow at index 2
==== called cellForRow at index 2
???? called heightForRow at index 2

如您所见,当您 didSelectRowAtIndexPath 时,heightForRowAtIndexPath 被循环调用多次,直到 swift 确定它具有正确的所有高度。同时,cellForRow 在您 select 编辑的单元格上仅被称为

因此,如果您的单元格在您 select 另一个单元格时自动折叠,您必须意识到它们在折叠时不是 运行 任何代码(例如隐藏元素的方法),因为 cellForRowAtIndexPath 仅在点击的单元格上被调用。

可以 hide/unhide 在您的 heightForRow 代码中,但是该代码被调用了太多次,以至于它确实不是最佳的。代码只应在需要时调用一次。因此,IMO 的最佳解决方案是在 editingStyleForRowAtIndexPath

中调用它

在您的 UITableViewCell 子类中,覆盖 willTransitionToState(state: UITableViewCellStateMask) 方法并将 contentView.clipToBounds 设置为 true,如下所示:

override func willTransitionToState(state: UITableViewCellStateMask) {
    super.willTransitionToState(state)

    contentView.clipsToBounds = true
}

从现在开始,它将正确裁剪单元格的子视图。