ios - Scrollview 中的两个动态 Stackview
问题描述
这是我的视图的层次结构
ScrollView
-> View
-> Stackview1
-> view1
-> view2
.
.
.
-> Stackview1
-> view1
-> view2
.
.
.
所以这里我的stackview的高度是根据.swift文件中添加的视图动态生成的
如果我给超级视图提供底部约束,它只适用于单个堆栈视图,但如果我同时使用两个堆栈视图,则不会考虑第二个堆栈视图。
解决方案
很难说出问题所在,因为您尚未发布约束,但解决方案非常简单:
您需要以下约束:
滚动视图:
topAnchor
至view.topAnchor
leadingAnchor
至view.leadingAnchor
trailingAnchor
至view.trailingAnchor
bottomAnchor
至view.bottomAnchor
包装 2 个 UIStackViews 的 UIView:
topAnchor
至scrollView.topAnchor
leadingAnchor
至scrollView.leadingAnchor
trailingAnchor
至scrollView.trailingAnchor
bottomAnchor
至scrollView.bottomAnchor
上层堆栈视图:
topAnchor
至wrapperView.topAnchor
leadingAnchor
至wrapperView.leadingAnchor
trailingAnchor
至wrapperView.trailingAnchor
widthAnchor
toscrollView.widthAnchor
(定义 ScrollView 的宽度contentSize
)
较低的 StackView:
topAnchor
至upperStackView.bottomAnchor
leadingAnchor
至wrapperView.leadingAnchor
trailingAnchor
至wrapperView.trailingAnchor
bottomAnchor
至wrapperView.bottomAnchor
现在,当您UIView
向其中一个中添加一个时UIStackViews
,UIScrollView 会自动更新。
这是一个工作示例:(我添加了两个以向两者UIButtons
添加更多)UIViews
UIStackViews
class ViewController: UIViewController {
let upperStackView = UIStackView()
let lowerStackView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
let scrollView = UIScrollView()
view.addSubview(scrollView)
scrollView.backgroundColor = .white
scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
let wrapperView = UIView()
scrollView.addSubview(wrapperView)
wrapperView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
wrapperView.topAnchor.constraint(equalTo: scrollView.topAnchor),
wrapperView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
wrapperView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
wrapperView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
])
upperStackView.axis = .vertical
upperStackView.distribution = .equalSpacing
upperStackView.alignment = .fill
wrapperView.addSubview(upperStackView)
upperStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
upperStackView.topAnchor.constraint(equalTo: wrapperView.topAnchor),
upperStackView.leadingAnchor.constraint(equalTo: wrapperView.leadingAnchor),
upperStackView.trailingAnchor.constraint(equalTo: wrapperView.trailingAnchor),
upperStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
])
lowerStackView.axis = .vertical
lowerStackView.distribution = .equalSpacing
lowerStackView.alignment = .fill
wrapperView.addSubview(lowerStackView)
lowerStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
lowerStackView.topAnchor.constraint(equalTo: upperStackView.bottomAnchor),
lowerStackView.leadingAnchor.constraint(equalTo: wrapperView.leadingAnchor),
lowerStackView.trailingAnchor.constraint(equalTo: wrapperView.trailingAnchor),
lowerStackView.bottomAnchor.constraint(equalTo: wrapperView.bottomAnchor)
])
for _ in 0...3 {
addView(to: upperStackView)
addView(to: lowerStackView)
}
let lowerButton = UIButton(type: .system)
lowerButton.setTitle("Add to lower StackView", for: .normal)
lowerButton.backgroundColor = .white
lowerButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(lowerButton)
NSLayoutConstraint.activate([
lowerButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -60),
lowerButton.widthAnchor.constraint(equalToConstant: 240),
lowerButton.heightAnchor.constraint(equalToConstant: 44),
lowerButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
lowerButton.addTarget(self, action: #selector(addViewToLowerStackView), for: .touchUpInside)
let upperButton = UIButton(type: .system)
upperButton.setTitle("Add to upper StackView", for: .normal)
upperButton.backgroundColor = .white
upperButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(upperButton)
NSLayoutConstraint.activate([
upperButton.bottomAnchor.constraint(equalTo: lowerButton.topAnchor, constant: -20),
upperButton.widthAnchor.constraint(equalToConstant: 240),
upperButton.heightAnchor.constraint(equalToConstant: 44),
upperButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
upperButton.addTarget(self, action: #selector(addViewToUpperStackView), for: .touchUpInside)
}
func addView(to stackView: UIStackView) {
let view = UIView()
view.backgroundColor = stackView == upperStackView ? .blue : .green
view.alpha = CGFloat(stackView.arrangedSubviews.count + 1) * 0.1
view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([view.heightAnchor.constraint(equalToConstant: 120)])
stackView.addArrangedSubview(view)
}
@objc func addViewToUpperStackView() {
addView(to: upperStackView)
}
@objc func addViewToLowerStackView() {
addView(to: lowerStackView)
}
}
更新:
您也可以仅使用 Storyboard 来完成这项工作:
推荐阅读
- javascript - 文件名只能包含 ASCII 32-126 字符,一些特殊字符除外
- amazon-web-services - 是否可以在 AWS Neptune 上将 GeoSparql 与 GeoJSON 对象一起使用?
- apache-storm - 如何修复“无法从种子主机中找到领导灵气 [192.168.23.165]
- jquery - 如何在输入范围内禁用鼠标滚动
- swift - 将字符串转换为 URL(为什么结果变量为零)
- javascript - 将自定义钩子注入进化函数的优雅方式
- missing-data - 写入操作后 dat 文件中缺少数据
- ios - UITableView 数据源更改不会触发 iOS 13 上的 UI 更新
- python - Python Flask 文件上传失败并出现 404 错误
- react-i18next - 没有 i18nKey 属性的 Trans 组件不渲染翻译