Autolayout:无法弄清楚如何解决与在 UITableViewCell 内扩展面板相关的警告
Autolayout: Can't figure out how to resolve warnings relating to expanding a panel inside a UITableViewCell
我有以下 UITableViewCell
布局:
布局由两个子视图组成:
TopView
(包含一个 Show
按钮)
BottomView
(按下 Show
按钮时展开或折叠)。
BottomView
由 3 个子视图组成。这些子视图的约束是:
三个子视图中的每一个都包含一个 UILabel
,它固定在 leading
、top
和 trailing
边上,并带有常量 == 8.
使用大于等于 8 的约束将 UILabel
固定到 UIView
的底部。这会强制 UILabel
与UIView
.
的顶部
三个 UIViews
中最左边的固定在 BottomView
的前缘。
- 三个
UIViews
中最右边的固定到 BottomView
的后缘
- 三个
UIViews
中的每一个都固定在 BottomView
的顶部
- 三个
UIViews
中的每一个都固定在 BottomView
的底部
- 三个视图的宽度和高度都相等。
BottomView
的底部固定到 UITableViewCell
的内容视图的底部
这给了我想要的布局:
我想要完成的是:
- 最初,
BottomView
应该折叠。
- 单击
Show
按钮应根据需要展开或折叠 BottomView
。
我设法通过创建一个最初卸载的 bottomViewHeightConstraint
来做到这一点。点击 show
按钮 activates/deactivates 约束。
AnotherTableViewCell.m
-(IBAction) show
{
self.bottomViewHeightConstraint.active = !self.bottomViewHeightConstraint.active;
[UIView animateWithDuration:0.3 animations:^{
[self layoutIfNeeded];
[self.delegate cellRequiresUpdates:self];
} completion:^(BOOL finished) {
}];
}
UIViewController.m
-(void) cellRequiresUpdates:(AnotherTableViewCell *)cell
{
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
这行得通,但针对无法满足的约束产生了很多警告。我想了解我的哪些约束导致了警告。
不可满足的约束是:
bottomViewHeightConstraint
== 0
(需要,因为我想折叠底视图)
UIBottomView
中最左边和最右边的 UIView
高度相等
(已尝试停用,但警告并未消失)
- 最左边的UIView底部与
BottomView
底部之间的8像素距离
(已尝试停用,但警告并未消失)
- 最左边的 UIView 底部与
BottomView
底部之间的 8 像素距离
(已尝试停用,但警告并未消失)
一些粗略的现成代码可以满足您的需求 -
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var expanded: [Bool] = [false, false, false, false]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 64.0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! ExpandingCell
cell.isExpanded = self.expanded[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? ExpandingCell {
let isExpanded = !self.expanded[indexPath.row]
self.expanded[indexPath.row] = isExpanded
cell.isExpanded = isExpanded
tableView.beginUpdates()
tableView.endUpdates()
}
}
}
class ExpandingCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
public var isExpanded = false {
didSet {
if self.isExpanded {
self.label.text = "Lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots of text"
} else {
self.label.text = "Not a lot of text"
}
}
}
}
请记住,单元格中的视图必须限制在 contentView 的顶部和底部,自动布局正确意味着当您在这种情况下更改标签的内容时,单元格将正确调整大小。
好的 - 这可以解决您的问题。在处理类似的最近问题时,我在 Apple 的文档中遇到了这个问题:
NOTE Don’t feel obligated to use all 1000 priority values. In fact, priorities should general cluster around the system-defined low (250), medium (500), high (750), and required (1000) priorities. You may need to make constraints that are one or two points higher or lower than these values, to help prevent ties. If you’re going much beyond that, you probably want to reexamine your layout’s logic.
当然,在 IB 中创建约束时,它们似乎默认使用 1000。
因此,对于您的特定布局...
Select 底部视图的所有约束,除了 Bottom View Height Constraint
:
并将 Priority
更改为 998
然后,select 仅 Bottom View Height Constraint
并将其 Priority
设置为 999
运行 您的应用程序和 show/hide 您心仪的底部视图 :)
我有以下 UITableViewCell
布局:
布局由两个子视图组成:
TopView
(包含一个Show
按钮)BottomView
(按下Show
按钮时展开或折叠)。
BottomView
由 3 个子视图组成。这些子视图的约束是:
三个子视图中的每一个都包含一个
UILabel
,它固定在leading
、top
和trailing
边上,并带有常量 == 8.使用大于等于 8 的约束将
UILabel
固定到UIView
的底部。这会强制UILabel
与UIView
. 的顶部
三个
UIViews
中最左边的固定在BottomView
的前缘。- 三个
UIViews
中最右边的固定到BottomView
的后缘
- 三个
UIViews
中的每一个都固定在BottomView
的顶部
- 三个
UIViews
中的每一个都固定在BottomView
的底部
- 三个视图的宽度和高度都相等。
BottomView
的底部固定到UITableViewCell
的内容视图的底部
这给了我想要的布局:
我想要完成的是:
- 最初,
BottomView
应该折叠。 - 单击
Show
按钮应根据需要展开或折叠BottomView
。
我设法通过创建一个最初卸载的 bottomViewHeightConstraint
来做到这一点。点击 show
按钮 activates/deactivates 约束。
AnotherTableViewCell.m
-(IBAction) show
{
self.bottomViewHeightConstraint.active = !self.bottomViewHeightConstraint.active;
[UIView animateWithDuration:0.3 animations:^{
[self layoutIfNeeded];
[self.delegate cellRequiresUpdates:self];
} completion:^(BOOL finished) {
}];
}
UIViewController.m
-(void) cellRequiresUpdates:(AnotherTableViewCell *)cell
{
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
这行得通,但针对无法满足的约束产生了很多警告。我想了解我的哪些约束导致了警告。 不可满足的约束是:
bottomViewHeightConstraint
== 0
(需要,因为我想折叠底视图)
UIBottomView
中最左边和最右边的
UIView
高度相等
(已尝试停用,但警告并未消失)
- 最左边的UIView底部与
BottomView
底部之间的8像素距离
(已尝试停用,但警告并未消失)
- 最左边的 UIView 底部与
BottomView
底部之间的 8 像素距离
(已尝试停用,但警告并未消失)
一些粗略的现成代码可以满足您的需求 -
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var expanded: [Bool] = [false, false, false, false]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 64.0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! ExpandingCell
cell.isExpanded = self.expanded[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? ExpandingCell {
let isExpanded = !self.expanded[indexPath.row]
self.expanded[indexPath.row] = isExpanded
cell.isExpanded = isExpanded
tableView.beginUpdates()
tableView.endUpdates()
}
}
}
class ExpandingCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
public var isExpanded = false {
didSet {
if self.isExpanded {
self.label.text = "Lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots & lots of text"
} else {
self.label.text = "Not a lot of text"
}
}
}
}
请记住,单元格中的视图必须限制在 contentView 的顶部和底部,自动布局正确意味着当您在这种情况下更改标签的内容时,单元格将正确调整大小。
好的 - 这可以解决您的问题。在处理类似的最近问题时,我在 Apple 的文档中遇到了这个问题:
NOTE Don’t feel obligated to use all 1000 priority values. In fact, priorities should general cluster around the system-defined low (250), medium (500), high (750), and required (1000) priorities. You may need to make constraints that are one or two points higher or lower than these values, to help prevent ties. If you’re going much beyond that, you probably want to reexamine your layout’s logic.
当然,在 IB 中创建约束时,它们似乎默认使用 1000。
因此,对于您的特定布局...
Select 底部视图的所有约束,除了 Bottom View Height Constraint
:
并将 Priority
更改为 998
然后,select 仅 Bottom View Height Constraint
并将其 Priority
设置为 999
运行 您的应用程序和 show/hide 您心仪的底部视图 :)