具有动态调整单元格的可折叠表格视图
Posted
技术标签:
【中文标题】具有动态调整单元格的可折叠表格视图【英文标题】:Collapsable Tableview with Dynamic sizing cells 【发布时间】:2017-04-16 17:51:00 【问题描述】:我一直在尝试遵循this github 教程,但是它们不是静态单元格,而是动态的,因为我不知道编译时的高度。
在 tableViewController 中,我将heightForRowAt
设置为0
或UITableViewAutomaticDimension
,具体取决于该部分是否折叠。与estimatedHeightForRowAt
类似,该值是0
,如果展开,则为更高的值。
现在解决问题,我已将UITableViewCell
子类化,当调用 cellForRowAt 时,它将添加一个如下所示的子视图:
override func addSubview(_ view: UIView)
guard view != nil else return
for view in self.subviews
view.removeFromSuperview()
super.addSubview(view)
//view.applyLeadingAndTrailingPinConstraint(toSuperview: 0)
//view.applyTopAndBottomPinConstraint(toSuperview: 0)
let addedView = self.subviews[0]
let bottom = NSLayoutConstraint(item: addedView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)
bottom.priority = 750
bottom.isActive = true
NSLayoutConstraint(item: addedView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: addedView, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: addedView, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: addedView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: addedView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
//NSLayoutConstraint.reportAmbiguity(v: self)
if addedView.hasAmbiguousLayout
print("Horizontal: \(addedView.constraintsAffectingLayout(for: .horizontal))")
print("Vertical: \(addedView.constraintsAffectingLayout(for: .vertical))")
print("Trace: \(addedView.value(forKey: "_autolayoutTrace"))")
//addedView.exerciseAmbiguityInLayout()
//print("self: \(self.frame), subview: \(self.subviews[0].frame)")
如您所见,问题在于约束有歧义,因此使用了hasAmbigousLayout
。当视图折叠时没有错误。然而,当我展开视图时,也有高度限制,就会出现歧义。以下是hasAmbigousLayout
内的3条打印语句的输出:
Horizontal: []
Vertical: [<NSLayoutConstraint:0x60800028ea10 UIView:0x7fcfe856a790.height == 100 (active)>]
Trace: Optional(
•ViraVira_Info.WellnessCell:0x7fcfe8859a00'cell', MISSING HOST CONSTRAINTS
| *UIView:0x7fcfe856a790- AMBIGUOUS LAYOUT for UIView:0x7fcfe856a790.minXid: 776, UIView:0x7fcfe856a790.minYid: 771, UIView:0x7fcfe856a790.Widthid: 778
Legend:
* - is laid out with auto layout
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
• - layout engine host)
我已尝试按照this 问题中的建议降低底部约束优先级。我还尝试了许多其他网站,但遗憾的是我忘记了这些网站。 应用程序中的结果是视图甚至没有显示,因为它应该有一个红色背景,当我尝试打印子视图的框架时,宽度为 0,这看起来很奇怪。
我可能在约束方面犯了一个愚蠢的错误,但经过 2 天的尝试,我仍然无法弄清楚。
感谢您的宝贵时间 -豪尔赫
【问题讨论】:
【参考方案1】:有几个问题需要注意(并且可能是问题的一部分):
override func addSubview(_ view: UIView)
-> 我认为这不是您的代码的正确位置。我已经开发了几年 ios 并且从来没有理由重写该方法。视图布局应该在 Interface Builder 或父视图中完成。
guard view != nil else return
-> 应该给你一个警告,因为 view 不是可选的(UIView?),所以它不能为零。这项检查根本没有用处。
for view in self.subviews view.removeFromSuperview() super.addSubview(view)
-> 这将删除之前添加的所有视图,最后添加的视图将赢得比赛,这完全出乎 addSubview 的调用者的意料 - 如果一个单元格添加多个子视图,这将导致麻烦和头痛。
let addedView = self.subviews[0]
-> 必须是相等视图,那为什么不在后面的代码中使用视图呢?
6 * NSLayoutConstraint
-> 视图通常由 4 个约束定位,2 个垂直和 2 个水平 - 我认为你应该删除最后两个(中心约束) - 这可能是你的问题。
尝试重构您的代码...
【讨论】:
感谢您的回答,但让我们分分合合吧。 1)也许没有必要继承addSubview,但这是最简单的,但我会将约束移动到layoutSubviews。 2) 这实际上是一个错误,因为我作为参数传递的值是一个 UIView!,并给了我一个 nil 值,这不应该是可能的,但它确实发生了。 3)我不知道如何创建cellForRowAt所以我通过添加一个子视图来解决它,这会导致多次相同的视图,所以我先删除另一个然后重新添加它,也许你可以帮我找到一个更好的解决方案。 4) 那只是一个错误:)。 5)我试图只用 4 来做,但它没有改变任何东西。我仍然遇到同样的错误。 2) 您不应该使用变通方法来修复错误。尝试找到 nil 情况的原因并修复它。 3)已经有一些关于表格视图和单元格加载的文档。太多的评论或答案。见:***.com/documentation/ios/791/…以上是关于具有动态调整单元格的可折叠表格视图的主要内容,如果未能解决你的问题,请参考以下文章