在 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】:我猜这是由于缺少一些约束。与标题标签一样,您只需将其设置为 Leading
、Top
和 Bottom
尝试设置似乎缺少的 height 和 width 约束。 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 单元格相同的顺序将文本字段值保存在数组中
如何在swift 4中重新排序单元格后保存tableView顺序