Autolayout 我可以将 CenterY 与顶部和底部约束结合使用吗?
Autolayout Can I combine CenterY with Top and Bottom Constraints?
我正试图让这个布局以某种方式动态化。这里的选项是动态的(未知数量),因此我们可以轻松地将这些选项放在 tableView、collectionView 或只是简单的 scrollView 中。
问题是我想让这个白色容器尽可能小并且垂直居中。当我将 centerY 约束与 Top+Bottom insets 结合使用时,似乎只有顶部和底部约束被激活。
And when the options are quite long, options can be scrollable, BUT maintaining the fact that there are top and bottom insets.
心里已经有了一些想法,比如观察container view的高度是否超过设备高度
我用的是snapKit,但是约束应该是可以理解的。这是我当前的布局:
func setupUI() {
self.view.backgroundColor = .clear
self.view.addSubviews(
self.view_BGFilter,
self.view_Container
)
self.view_BGFilter.snp.makeConstraints {
[=10=].edges.equalToSuperview()
}
self.view_Container.snp.makeConstraints {
[=10=].centerY.equalToSuperview().priority(.high)
//[=10=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0).priority(.medium)
[=10=].leading.trailing.equalToSuperview().inset(16.0)
}
// Setup container
self.view_Container.addSubviews(
self.label_Title,
self.stackView,
self.button_Submit
)
self.label_Title.snp.makeConstraints {
[=10=].top.equalToSuperview().inset(40.0)
[=10=].leading.trailing.equalToSuperview().inset(16.0)
}
self.stackView.snp.makeConstraints {
[=10=].top.equalTo(self.label_Title.snp.bottom).offset(29.0)
[=10=].leading.trailing.equalToSuperview().inset(24.0)
}
self.button_Submit.snp.makeConstraints {
[=10=].height.equalTo(52.0)
[=10=].top.equalTo(self.stackView.snp.bottom).offset(30.0)
[=10=].bottom.leading.trailing.equalToSuperview().inset(24.0)
}
self.generateButtons()
}
我回答你的问题 - CenterY 有顶部和底部约束? - 附带一点评论...
我知道 SnapKit 很受欢迎,我敢肯定它有时会很有帮助,尤其是如果您一直使用它的话。
但是...在使用它时,您永远无法完全确定它在做什么。而且,根据我的经验,使用 SnapKit 的人通常并不真正理解约束是什么或它们是如何工作的(并不意味着 you 就是这种情况......只是观察观察各种问题)。
在这种特定情况下,要么是 SnapKit 有一点错误,要么是这一行不太适合预期的结果:
[=10=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
你可以通过简单的测试来确认:
class TestViewController: UIViewController {
let testView: UIView = {
let v = UIView()
v.backgroundColor = .red
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(testView)
testView.snp.makeConstraints {
[=11=].centerY.equalToSuperview()
// height exactly 200 points
[=11=].height.equalTo(200.0)
// top and bottom at least 80 points from superview
[=11=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
[=11=].leading.trailing.equalToSuperview().inset(16.0)
}
}
}
这是结果...以及调试控制台中的 [LayoutConstraints] Unable to simultaneously satisfy constraints.
消息:
如果我们按如下方式替换该行:
// replace this line
//[=12=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
// with these two lines
[=12=].top.greaterThanOrEqualToSuperview().offset(80.0)
[=12=].bottom.lessThanOrEqualToSuperview().offset(-80.0)
这肯定似乎在做同样的事情,我们得到了我们预期的结果:
所以,SnapKit 中有些东西是可疑的。
这将解决您的问题。像这样更改 view_Container
约束设置:
self.view_Container.snp.makeConstraints {
[=13=].centerY.equalToSuperview().priority(.required)
// replace this line
//[=13=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
// with these two lines
[=13=].top.greaterThanOrEqualToSuperview().offset(80.0)
[=13=].bottom.lessThanOrEqualToSuperview().offset(-80.0)
[=13=].leading.trailing.equalToSuperview().inset(16.0)
}
变更前:
变更后:
关于在你有很多选项按钮时添加滚动,我可以给你一个滚动全部内容或滚动仅的例子] 选项按钮。
我正试图让这个布局以某种方式动态化。这里的选项是动态的(未知数量),因此我们可以轻松地将这些选项放在 tableView、collectionView 或只是简单的 scrollView 中。
问题是我想让这个白色容器尽可能小并且垂直居中。当我将 centerY 约束与 Top+Bottom insets 结合使用时,似乎只有顶部和底部约束被激活。
And when the options are quite long, options can be scrollable, BUT maintaining the fact that there are top and bottom insets.
心里已经有了一些想法,比如观察container view的高度是否超过设备高度
我用的是snapKit,但是约束应该是可以理解的。这是我当前的布局:
func setupUI() {
self.view.backgroundColor = .clear
self.view.addSubviews(
self.view_BGFilter,
self.view_Container
)
self.view_BGFilter.snp.makeConstraints {
[=10=].edges.equalToSuperview()
}
self.view_Container.snp.makeConstraints {
[=10=].centerY.equalToSuperview().priority(.high)
//[=10=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0).priority(.medium)
[=10=].leading.trailing.equalToSuperview().inset(16.0)
}
// Setup container
self.view_Container.addSubviews(
self.label_Title,
self.stackView,
self.button_Submit
)
self.label_Title.snp.makeConstraints {
[=10=].top.equalToSuperview().inset(40.0)
[=10=].leading.trailing.equalToSuperview().inset(16.0)
}
self.stackView.snp.makeConstraints {
[=10=].top.equalTo(self.label_Title.snp.bottom).offset(29.0)
[=10=].leading.trailing.equalToSuperview().inset(24.0)
}
self.button_Submit.snp.makeConstraints {
[=10=].height.equalTo(52.0)
[=10=].top.equalTo(self.stackView.snp.bottom).offset(30.0)
[=10=].bottom.leading.trailing.equalToSuperview().inset(24.0)
}
self.generateButtons()
}
我回答你的问题 - CenterY 有顶部和底部约束? - 附带一点评论...
我知道 SnapKit 很受欢迎,我敢肯定它有时会很有帮助,尤其是如果您一直使用它的话。
但是...在使用它时,您永远无法完全确定它在做什么。而且,根据我的经验,使用 SnapKit 的人通常并不真正理解约束是什么或它们是如何工作的(并不意味着 you 就是这种情况......只是观察观察各种问题)。
在这种特定情况下,要么是 SnapKit 有一点错误,要么是这一行不太适合预期的结果:
[=10=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
你可以通过简单的测试来确认:
class TestViewController: UIViewController {
let testView: UIView = {
let v = UIView()
v.backgroundColor = .red
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(testView)
testView.snp.makeConstraints {
[=11=].centerY.equalToSuperview()
// height exactly 200 points
[=11=].height.equalTo(200.0)
// top and bottom at least 80 points from superview
[=11=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
[=11=].leading.trailing.equalToSuperview().inset(16.0)
}
}
}
这是结果...以及调试控制台中的 [LayoutConstraints] Unable to simultaneously satisfy constraints.
消息:
如果我们按如下方式替换该行:
// replace this line
//[=12=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
// with these two lines
[=12=].top.greaterThanOrEqualToSuperview().offset(80.0)
[=12=].bottom.lessThanOrEqualToSuperview().offset(-80.0)
这肯定似乎在做同样的事情,我们得到了我们预期的结果:
所以,SnapKit 中有些东西是可疑的。
这将解决您的问题。像这样更改 view_Container
约束设置:
self.view_Container.snp.makeConstraints {
[=13=].centerY.equalToSuperview().priority(.required)
// replace this line
//[=13=].top.bottom.greaterThanOrEqualToSuperview().inset(80.0)
// with these two lines
[=13=].top.greaterThanOrEqualToSuperview().offset(80.0)
[=13=].bottom.lessThanOrEqualToSuperview().offset(-80.0)
[=13=].leading.trailing.equalToSuperview().inset(16.0)
}
变更前:
变更后:
关于在你有很多选项按钮时添加滚动,我可以给你一个滚动全部内容或滚动仅的例子] 选项按钮。