我创建了一个 UIView,其中有按钮。我这样设置约束:
NSLayoutConstraint.activate([
sampleView.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 20),
sampleView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
sampleView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
])
没有添加任何高度或底部锚点,因为我希望它的高度是动态的。 最初,sampleView 没有按钮,因此它不会出现在 UI 中。然后我在其中添加彼此垂直的按钮,效果很好。
我现在面临的问题是,在这个sampleView下面还有另一个视图(tempView)。最初我将 tempView 的 topAnchor 设置为sampleView 的bottomAnchor。 所以它最初就正确地放置在屏幕上。
当我在 SampleView 中添加按钮时,它会展开,但 tempView 不会。我尝试使用 view.layoutIfNeeded() 并使用sampleView的新高度设置topAnchor,但对我来说没有任何效果。
请帮我解决这个问题。
您必须做某事才能给
sampleView
一个高度。
一种简单的方法是添加垂直
UIStackView
作为 sampleView
的子视图,将所有 4 个边约束为 sampleView
,然后添加按钮作为堆栈视图的排列子视图。
简单示例:
class ExampleVC: UIViewController {
let topView = UIView()
let sampleView = UIView()
let tempView = UIView()
// let's use a vertical stack view to hold the buttons inside sampleView
let stackView = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
[topView, sampleView, tempView].forEach { v in
v.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v)
}
topView.backgroundColor = .yellow
sampleView.backgroundColor = .green
tempView.backgroundColor = .cyan
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
topView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
topView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0),
topView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -16.0),
topView.heightAnchor.constraint(equalToConstant: 100.0),
sampleView.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 20.0),
sampleView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0),
sampleView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -16.0),
// sampleView has no Height constraint ...
// we're adding a stack view to it, and as we add buttons to the stack view
// it will control the Height
tempView.topAnchor.constraint(equalTo: sampleView.bottomAnchor, constant: 20.0),
tempView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 16.0),
tempView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -16.0),
tempView.heightAnchor.constraint(equalToConstant: 100.0),
])
// stackView to hold the buttons
stackView.axis = .vertical
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
sampleView.addSubview(stackView)
NSLayoutConstraint.activate([
// constrain all 4 sides of the stack view to sampleView
stackView.topAnchor.constraint(equalTo: sampleView.topAnchor, constant: 0.0),
stackView.leadingAnchor.constraint(equalTo: sampleView.leadingAnchor, constant: 0.0),
stackView.trailingAnchor.constraint(equalTo: sampleView.trailingAnchor, constant: 0.0),
stackView.bottomAnchor.constraint(equalTo: sampleView.bottomAnchor, constant: 0.0),
])
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let btnNumber = stackView.arrangedSubviews.count + 1
let btn = UIButton()
btn.backgroundColor = .red
btn.setTitle("Button \(btnNumber)", for: [])
stackView.addArrangedSubview(btn)
}
}
开始时,因为我们没有向堆栈视图添加任何按钮,所以它看起来像这样:
点击任意位置即可添加按钮——这是第一次点击后我们得到的结果:
再点击几次后:
class ViewController: UIViewController {
///Variable
var viewA: UIView!
///View lifecycle functions
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
viewA = UIView()
viewA.translatesAutoresizingMaskIntoConstraints = false
viewA.backgroundColor = .red
view.addSubview(viewA)
let viewB = UIView()
viewB.translatesAutoresizingMaskIntoConstraints = false
viewB.backgroundColor = .green
view.addSubview(viewB)
NSLayoutConstraint.activate([
viewA.topAnchor.constraint(equalTo: view.topAnchor, constant: 20),
viewA.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
viewA.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
viewB.topAnchor.constraint(equalTo: viewA.bottomAnchor, constant: 20),
viewB.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
viewB.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
viewB.heightAnchor.constraint(equalToConstant: 50),
])
viewA.layoutIfNeeded()
setupSubview()
}
override func viewDidLayoutSubviews() {
view.layoutIfNeeded()
}
func setupSubview(){
DispatchQueue.main.asyncAfter(deadline: .now() + 5 ) {
let viewSub = UIView()
viewSub.translatesAutoresizingMaskIntoConstraints = false
viewSub.backgroundColor = .purple
self.viewA.addSubview(viewSub)
NSLayoutConstraint.activate([
viewSub.topAnchor.constraint(equalTo: self.viewA.topAnchor, constant: 20),
viewSub.leadingAnchor.constraint(equalTo: self.viewA.leadingAnchor, constant: 16),
viewSub.trailingAnchor.constraint(equalTo: self.viewA.trailingAnchor, constant: -16),
viewSub.heightAnchor.constraint(equalToConstant: 60),
viewSub.bottomAnchor.constraint(equalTo: self.viewA.bottomAnchor)
])
self.viewA.layoutIfNeeded()
print(self.viewA.frame)
}
}
}