UITableViewCell 子视图显示在单元格之外

Posted

技术标签:

【中文标题】UITableViewCell 子视图显示在单元格之外【英文标题】:UITableViewCell subviews are displaying outside of cell 【发布时间】:2020-01-14 21:21:42 【问题描述】:

在我的 UITableView 的一部分中,有 5 个单元格,其中三个已配置为展开/折叠以在选中时提供更详细的视图。其中一个单元格显示了许多小方块的图表,这些小方块显示完美,直到另一个单元格展开,如下所示:

但是,当单元格折叠时,单元格中的子视图会显示在不同的单元格、不同的部分中,如下所示:

还有这个:

要在单元格中创建子视图,这是我在 cellForRow 方法中的代码,它只使用 UIViews 数组:

for vote in vote_array 
    cell.contentView.addSubview(vote as? UIView ?? UIView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0)))
            

我尝试在添加之前删除所有子视图,但它不会改变任何东西:

for subview in cell.contentView.subviews 
                subview.removeFromSuperview()
            

编辑:这是在 switch 语句中,但这里是相关的单元格/案例 cellForRow:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.contentView.clipsToBounds = true
            cell.clipsToBounds = true
            let vote_array = getVoteArray()

            for subview in cell.contentView.subviews 
                subview.removeFromSuperview()
            

            for case let vote as UIView in vote_array 
                cell.contentView.addSubview(vote)
            

编辑: getVoteArray的核心:

func getVoteArray() -> NSMutableArray 
    var i = 0
    var x = 20
    var y = 4
    let blockViews : NSMutableArray = []
    for color in blocks 
        let block = UIView.init(frame: CGRect.init(x: x, y: y, width: 20, height: 20))
        block.backgroundColor = color as? UIColor
        blockViews.add(block)
        x = x + 24
        i = i + 1
        if i == num_blocks_per_row  i = 0; y = y + 24; x = 20 
    
    diagramHeight = y + 24
    return blockViews

我似乎无法弄清楚为什么子视图在整个 tableView 中随机生成。

【问题讨论】:

您先将单元格出列?但是在添加新子视图之前,您是否删除了所有子视图?如果没有,您可以保留多个视图。 注意:可以用 CGRect.zeo 代替 CGRect.int()。打字和阅读速度更快。 @claude31 在我添加子视图之前,我这样做是为了删除它们:for subview in cell.contentView.subviews subview.removeFromSuperview() 您能否发布 cellAtRow 的完整代码。 谢谢。不确定这一点,但 vote_array 是一个 UIViews 数组。精确的 ?因此,它们是对 UIViews 的引用(需要查看 getVoteArray():您是创建新的 UIView 实例还是使用已经创建的实例?)。如果是后者,那么当您添加子视图时,您将删除所有其他链接到任何超级视图。 [参见 addSubview 上的文档:视图只能有一个超级视图。如果视图已经有一个超级视图并且该视图不是接收者,则此方法会在将接收者设为新的超级视图之前删除先前的超级视图。] 【参考方案1】:

添加完毕

for case let cell as UITableViewCell in tableView.subviews 
    for subview in cell.contentView.subviews 
        if subview.tag == 115 
            subview.removeFromSuperview()
        
    

到我的didSelectRowAt 方法,在创建每个视图时添加标签之后。我仍然不确定为什么将视图添加到不同的单元格,但这至少消除了它们。

【讨论】:

视图被添加到不同的单元格,因为它们正在被重用。来自indexPath(row: 0, section: 0) 的视图可以重用于indexPath(row: 1, section: 0)。我建议你继承UITableViewCell,这样你就不必做subview.removeFromSuperview()【参考方案2】:

尝试为折叠和展开状态实现唯一的ReuseIdentifiers

如果单元格已折叠,则不要通过将所有这些 UIView 的高度为 0 或未添加到子视图的 collapsedCell 出列来加载其中的所有视图。

如果单元格被扩展而不是 deque 一个 expandCell ,其中视图的布局如第一个屏幕截图所示。

展开或折叠后调用tableview.reloadData()

【讨论】:

【参考方案3】:

很久很久以前,UIViews 剪裁了他们的孩子,但很长一段时间都不是这样。如果您想要剪辑,您需要将 UIView.clipsToBounds 更改为 true 或使用底层 CALayer 属性 maskToBounds。

cell.contentView.clipsToBounds = true

或者您可以选中故事板/笔尖中的框。

【讨论】:

以上是关于UITableViewCell 子视图显示在单元格之外的主要内容,如果未能解决你的问题,请参考以下文章

更改 UITableViewCell 中某些子视图的突出显示

UITableViewCell 子视图在重绘之前不显示

UITableViewCell 无法添加子视图

向左滑动时未剪切子视图以删除 UITableViewCell

点击单元格后不同的 UITableViewCell 子视图布局

如何在 UITableViewCell 上保留子视图