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

时间:2017-09-18 09:08:20

标签: ios swift uitableview swift3 ios11

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

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函数什么都不做。

这是表格在开头的样子: table right after building

这是我点击底部单元格后的样子: table after tapping cell

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

更令人好奇的是,如果我按下一个单元格,那个单元格和一个单元格会出现这个问题,而不是表格中的任何其他单元格。

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

点击单元格后,有什么可以改变约束的想法?

更新1:

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

  • 除了上面提到的限制之外,没有其他限制。

2 个答案:

答案 0 :(得分:0)

我想这是由于一些缺失的约束。与标题标签一样,您只需设置LeadingTopBottom尝试设置高度宽度似乎缺失了。

此外,我不认为调试器会在控制台中显示任何错误,如果您不使用故事板,那么如果您没有使用故事板,那么我们只需要在控制台中进行可视化分析,我们只得到冲突的约束信息。

<强>详细

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

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

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

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

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

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

    同样,它依赖于表示元素的大小应该是多少,如果它不固定并且应该从屏幕的边缘到边缘然后应用固定宽度约束我们需要设置width等于其超级视图,或者我们只能设置Leading和Trailing约束来满足它的宽度约束。

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

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

答案 1 :(得分:0)

我添加了像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)
}

Cell的高度为44,默认值为44。