Swift 尾随约束在表视图中未按预期工作
Swift trailing constraint not working as expected in tableview
我定义了 UITableView
扩展,其中包含将默认视图放置在 tableView 之上的功能。出于某种原因,以下代码行无法按预期工作。
1) 没有提供正确解决方案的代码
func addNoDataView() -> UIView {
let containerView = UIView(forAutoLayout: ())
self.addSubview(containerView)
containerView.backgroundColor = UIColor.black
containerView.autoPinEdge(.leading, to: .leading, of: self, withOffset: 8)
containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: 8)
containerView.autoPinEdge(.top, to: .top, of: self, withOffset: 40)
containerView.autoSetDimension(.height, toSize: 150)
return containerView
}
在这种情况下,预期输出将是一个黑色视图,距离 tableView 顶部 40 像素,具有前导和尾随边距。但是当我 运行 我什至看不到风景。
2) 提供正确解决方案的代码
func addNoDataView() -> UIView {
let containerView = UIView(forAutoLayout: ())
containerView.backgroundColor = UIColor.black
self.addSubview(containerView)
containerView.autoPinEdge(.leading, to: .leading, of: self, withOffset: 8)
containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: self.frame.width - 8)
containerView.autoPinEdge(.top, to: .top, of: self, withOffset: 40)
containerView.autoSetDimension(.height, toSize: 150)
return containerView
}
在这种情况下,我得到了预期的解决方案。即黑色视图距顶部 40,距 tableView 的后缘和前缘 8 作为边距,高度为 150。
我还有一个功能,与上面几乎相同,但差别很小(我认为)。
func addNoDataLabelToTableView() -> UILabel {
let label = UILabel(forAutoLayout: ())
self.addSubview(label)
label.textColor = UIColor.darkGray
label.textAlignment = .center
label.text = "No Data Available"
label.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: 8)
label.autoPinEdge(.leading, to: .leading, of: self, withOffset: 8)
label.autoSetDimension(.height, toSize: 20)
label.autoCenterInSuperview()
return label
}
此函数在 tableView 的中心添加了一个标签,并按预期完美运行。
tableView 在所有 4 个边上固定到它的 superview 边缘。没问题。
但是,我无法理解为什么案例 1 不起作用。有人可以解释一下这两行之间的区别吗?
1) containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: 8)
无效
2) containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: self.frame.width - 8)
效果出人意料。
您正在将 .containerView
添加到 UITableView
... 继承自 UIScrollView
。
滚动视图与约束的关系略有不同,因为它们还决定了滚动视图的 .contentSize
。
如果您真的想要将子视图添加到table视图(最好将其放在顶部,而不是放在里面,但无论如何...),您必须 为该子视图指定宽度和高度(除非它类似于 UILabel,它具有固有大小)。
因此,您需要将 addNoDataView()
函数更改为:
func addNoDataView() -> UIView {
let containerView = UIView(forAutoLayout: ())
self.addSubview(containerView)
containerView.backgroundColor = UIColor.black
// inset view 8-pts from left
containerView.autoPinEdge(.left, to: .left, of: self, withOffset: 8)
// inset view 40-pts from top
containerView.autoPinEdge(.top, to: .top, of: self, withOffset: 40)
// set width to width of self (a scrollview) -16 (inset 8 from left and 8 from right)
containerView.autoMatch(.width, to: .width, of: self, withOffset: -16.0)
// set explicit height to 150
containerView.autoSetDimension(.height, toSize: 150)
return containerView
}
我定义了 UITableView
扩展,其中包含将默认视图放置在 tableView 之上的功能。出于某种原因,以下代码行无法按预期工作。
1) 没有提供正确解决方案的代码
func addNoDataView() -> UIView {
let containerView = UIView(forAutoLayout: ())
self.addSubview(containerView)
containerView.backgroundColor = UIColor.black
containerView.autoPinEdge(.leading, to: .leading, of: self, withOffset: 8)
containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: 8)
containerView.autoPinEdge(.top, to: .top, of: self, withOffset: 40)
containerView.autoSetDimension(.height, toSize: 150)
return containerView
}
在这种情况下,预期输出将是一个黑色视图,距离 tableView 顶部 40 像素,具有前导和尾随边距。但是当我 运行 我什至看不到风景。
2) 提供正确解决方案的代码
func addNoDataView() -> UIView {
let containerView = UIView(forAutoLayout: ())
containerView.backgroundColor = UIColor.black
self.addSubview(containerView)
containerView.autoPinEdge(.leading, to: .leading, of: self, withOffset: 8)
containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: self.frame.width - 8)
containerView.autoPinEdge(.top, to: .top, of: self, withOffset: 40)
containerView.autoSetDimension(.height, toSize: 150)
return containerView
}
在这种情况下,我得到了预期的解决方案。即黑色视图距顶部 40,距 tableView 的后缘和前缘 8 作为边距,高度为 150。
我还有一个功能,与上面几乎相同,但差别很小(我认为)。
func addNoDataLabelToTableView() -> UILabel {
let label = UILabel(forAutoLayout: ())
self.addSubview(label)
label.textColor = UIColor.darkGray
label.textAlignment = .center
label.text = "No Data Available"
label.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: 8)
label.autoPinEdge(.leading, to: .leading, of: self, withOffset: 8)
label.autoSetDimension(.height, toSize: 20)
label.autoCenterInSuperview()
return label
}
此函数在 tableView 的中心添加了一个标签,并按预期完美运行。
tableView 在所有 4 个边上固定到它的 superview 边缘。没问题。
但是,我无法理解为什么案例 1 不起作用。有人可以解释一下这两行之间的区别吗?
1) containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: 8)
无效
2) containerView.autoPinEdge(.trailing, to: .trailing, of: self, withOffset: self.frame.width - 8)
效果出人意料。
您正在将 .containerView
添加到 UITableView
... 继承自 UIScrollView
。
滚动视图与约束的关系略有不同,因为它们还决定了滚动视图的 .contentSize
。
如果您真的想要将子视图添加到table视图(最好将其放在顶部,而不是放在里面,但无论如何...),您必须 为该子视图指定宽度和高度(除非它类似于 UILabel,它具有固有大小)。
因此,您需要将 addNoDataView()
函数更改为:
func addNoDataView() -> UIView {
let containerView = UIView(forAutoLayout: ())
self.addSubview(containerView)
containerView.backgroundColor = UIColor.black
// inset view 8-pts from left
containerView.autoPinEdge(.left, to: .left, of: self, withOffset: 8)
// inset view 40-pts from top
containerView.autoPinEdge(.top, to: .top, of: self, withOffset: 40)
// set width to width of self (a scrollview) -16 (inset 8 from left and 8 from right)
containerView.autoMatch(.width, to: .width, of: self, withOffset: -16.0)
// set explicit height to 150
containerView.autoSetDimension(.height, toSize: 150)
return containerView
}