在 tableView 中选择单元格后布局更改

Posted

技术标签:

【中文标题】在 tableView 中选择单元格后布局更改【英文标题】:Layout changes after selecting cell in tableView 【发布时间】:2017-09-18 09:08:20 【问题描述】:

我有一个普通的表格视图,其中包含使用以下代码配置的单元格:

override function tableView(...cellForRowAt indexPath: IndexPath) 
    let cell = tableView.dequeueReusableCell(myIdentifier) as CellClass

    cell.title.text = "this is a title"

    descriptionLabel = UILabel()
    descriptionLabel.numberOfLines = 0
    descriptionLabel.text = "this is a description"

    cell.accessoryView = UISwitch()

    // layout constraints
    leadingSpaceToSuperviewFor(cell.title)
    topSpaceToSuperviewFor(cell.title)
    bottomSpaceTo(view: label, from: cell.title) 

    leadingSpaceToSuperviewFor(label)
    toSpaceTo(view: cell.title, from: label)
    bottomSpaceToSuperviewFor(label)


func leadingSpaceToSuperviewFor (view: UILabel ) 
    if let superview = view.superview
        let constraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-[view]", options: [], metrics: [:], views: ["view": view])
        constraints.forEach( $0.priority = UILayoutPriorityRequired )
        superview.addConstraints(constraints)
    


func topSpaceToSuperviewFor (view: UILabel) 
    // same as above but with this constraint
    let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-[view]", options: [], metrics: [:], views: ["view": view])


func bottomSpaceToSuperviewFor (view: UILabel) 
    // same as above but with constraint
    let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view]-|", options: [], metrics: [:], views: ["view": view])


// other constraint functions follow the same pattern.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)  //do nothing 

代码生成,我得到了一个漂亮的表格。我的问题是当我单击单元格时单元格的标题失去了约束,即使 didSelectRowAt 函数什么也不做。

这是表格开始时的样子:

这是我点击底部单元格后的样子:

如您所见,标题的底部约束消失了。我在控制台中没有遇到任何约束冲突。

更奇怪的是,如果我按下一个单元格,那个单元格和上面的那个单元格都会有这个问题,而表格中的任何其他单元格都没有。

另外,如果我只是按下开关,它会相应地切换而不影响布局。

关于单击单元格后可能导致约束发生变化的任何想法?

更新 1:

没有 .xib 文件,要求只能通过编程方式解决。

除上述限制外,没有其他限制。

【问题讨论】:

您是否对自定义单元格设置了约束? 我是 swift 新手,所以我不明白你的意思。看到的所有约束都是存在的。 我想说你有没有对storyboard设置约束? 不,一切都是以编程方式完成的。 如果你要做这样的事情,那么为什么不直接使用:developer.apple.com/documentation/uikit/uitableviewcell/… 【参考方案1】:

我猜这是由于缺少一些约束。与标题标签一样,您只需将其设置为 LeadingTopBottom 尝试设置似乎缺少的 heightwidth 约束。 p>

另外,如果您不使用情节提要,我认为调试器不会在控制台中显示缺少约束的任何错误,那么对于缺少约束,我们只需要直观地分析这一点,但是,在控制台中,我们只得到了冲突的约束信息。

详情

为了对每个元素(视图、标签、图像等)设置约束需要两个

    元素位置 元素大小

1.Element position: 为了设置元素位置,您需要指定至少两个约束,即其 x 位置(距原点的水平空间)和 y 位置(距原点的垂直空间)。

_____________________________________________________________
|                              |
|                              |
|                         Top constraint
|                              |
|                              |
|---Leading constraint----[ Label ]
|
|

这取决于视图展示,我们可以设置前导和顶部,或者我们可以在容器中设置水平和在容器中垂直以使视图居中对齐。

2. Element size:对于元素的大小,[i]我们需要设置它的宽高约束。

_______________________________________________________________________
|                                  |                            
|                                  |                            
|                             Top constraint                            
|                                  |                            ^
|                                  |                            |
|---Leading constraint----[       Label          ]            Height
|                                                           constraint
|                          <---Width costraint--->              |
|                                                               ^
|

再次取决于表示,如果元素的大小不固定并且应该从屏幕的边缘到边缘,那么它应该像多少大小一样,而不是应用固定宽度约束,我们需要将宽度设置为等于它的超级视图,或者我们只能设置Leading和Trailing约束来满足它的宽度约束。

要了解有关以编程方式设置约束的更多信息,请查看Apple's VFL explanation(视觉格式语言)

好教程:https://www.raywenderlich.com/110393/auto-layout-visual-format-language-tutorial

【讨论】:

【参考方案2】:

我像 NSIceCode 建议的那样添加了高度和宽度,但这不起作用。这完成了工作:

tableView(...cellForRowAt ...) 
    let cell = (tableView.dequeueReusableCell(myId) as? CellClass) ??
        CellClass(style: .subtitle, reuseIdentifier: myId)

最重要的是,我向开关添加了尾随约束:

tableView (...) 
   ...
   trailingSpaceToSuperviewFor(switchControl)
   topSpaceToSuperviewFor(switchControl)
   bottomSpaceToSuperviewFor(switchControl)
   trailingSpaceTo(switchControl, from: cell.title)
   trailingSpaceTo(switchControl, from: cell.detailTextLabel)

单元格的高度是 44,这是默认值。

【讨论】:

以上是关于在 tableView 中选择单元格后布局更改的主要内容,如果未能解决你的问题,请参考以下文章

删除单元格后刷新tableView

即使在删除某些单元格后,仍以与 TableView 单元格相同的顺序将文本字段值保存在数组中

为 iOS 选择 TableView 单元格时视图已更改

如何在swift 4中重新排序单元格后保存tableView顺序

在 TableView 中创建的 7 个单元格后添加部分 - Swift

无法识别单击单元格后的 tableView segue