Scrollview中的两个动态Stack View
Posted
技术标签:
【中文标题】Scrollview中的两个动态Stack View【英文标题】:Two dynamic Stackviews in Scrollview 【发布时间】:2018-09-15 23:38:01 【问题描述】:这是我的视图层次结构
ScrollView
-> View
-> Stackview1
-> view1
-> view2
.
.
.
-> Stackview1
-> view1
-> view2
.
.
.
所以这里我的 stackview 的高度是根据 .swift 文件中添加的视图动态生成的
如果我给超级视图提供底部约束,它只适用于单个堆栈视图,但如果我同时使用两个堆栈视图,则不会考虑第二个堆栈视图。
【问题讨论】:
如何为每个堆栈视图添加容器视图? 但是我的容器视图高度不能根据 stackview 增加 考虑在超级堆栈视图中添加两个堆栈视图。 ScrollView 包含包含两个堆栈视图的堆栈视图。 【参考方案1】:很难说问题出在哪里,因为您还没有发布您的限制条件,但解决方案非常简单:
您需要以下约束:
滚动视图:
topAnchor
到 view.topAnchor
leadingAnchor
到 view.leadingAnchor
trailingAnchor
到 view.trailingAnchor
bottomAnchor
到 view.bottomAnchor
包装了 2 个 UIStackView 的 UIView:
topAnchor
到 scrollView.topAnchor
leadingAnchor
到 scrollView.leadingAnchor
trailingAnchor
到 scrollView.trailingAnchor
bottomAnchor
到 scrollView.bottomAnchor
上层 StackView:
topAnchor
到 wrapperView.topAnchor
leadingAnchor
到 wrapperView.leadingAnchor
trailingAnchor
到 wrapperView.trailingAnchor
widthAnchor
to scrollView.widthAnchor
(定义ScrollView的contentSize
的宽度)
较低的 StackView:
topAnchor
到 upperStackView.bottomAnchor
leadingAnchor
到 wrapperView.leadingAnchor
trailingAnchor
到 wrapperView.trailingAnchor
bottomAnchor
到 wrapperView.bottomAnchor
现在,当您将UIView
添加到UIStackViews
之一时,UIScrollView 会自动更新。
这是一个工作示例:(我添加了两个 UIButtons
以向两个 UIStackViews
添加更多 UIViews
)
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)
更新:
您也可以仅使用情节提要完成这项工作:
【讨论】:
感谢您的回答,我添加了视图,因为我的视图中有一些其他标签 变化不大。我更新了我的答案以包括UIView
@再次感谢 joerm。所以我的问题是我需要两者都做吗?代码和通过故事板?因为我是从 stroyboard 设置的,所以它会导致我的 y 位置或滚动视图高度发生冲突错误
我的例子只是代码。不涉及情节提要。查看我更新的答案以获取仅使用情节提要的示例。
@PJR "conflicts error for y position or height of scrollview" 可以通过向堆栈视图添加一个或多个固定高度项(或设置最小高度约束)来解决以上是关于Scrollview中的两个动态Stack View的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - ScrollView 没有一直滚动到底部
如何在 SwiftUI 中设置 ScrollView 的 contentInset