gpt4 book ai didi

ios - 使用 NSLayoutConstraints 使用 Swift 在 ScrollView 中垂直对齐动态 View

转载 作者:搜寻专家 更新时间:2023-10-30 22:12:35 25 4
gpt4 key购买 nike

我有一个应用程序,它有一个动态生成的 View ,每次加载 View 时都可能不同。主视图包含一个设置为主视图边界的 ScrollView。然后将 subview 动态添加到 ScrollView,但这些 View 的高度不会相同,并且它们可以随时更改高度(例如,用户单击 View 内容并更改)。我想使用布局约束来确保每个 View 都与它上面的 View 保持对齐,并带有一些任意填充。见下图:

needed layout

现在所有的填充值都设置为 10(顶部、左侧和右侧)。我正在使用它们的框架手动设置这些 subview 的位置,但如果 View 大小发生变化,这将不起作用,所以我想将其更改为使用 NSLayoutConstraints,但我遇到了一些问题。

作为测试,我像以前一样设置 subview 的框架,但随后我添加了约束:

// newView is created and its frame is initialized
self.scrlView?.addSubview(newView)
let constr = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.previousView, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 10)
NSLayoutConstraints.activateConstraints([constr])
newView.translatesAutoResizingMaskIntoConstraints = false
self.previousView = newView

但是景色无处可寻。我究竟做错了什么?所需要做的就是确保每个 View 的顶部都在前一个 View 下方对齐,并且无论 View 高度如何,它们都保持这种状态。

此外,由于这些 View 都添加到 ScrollView ,使用上面的布局约束如何设置 ScrollView 的正确内容大小?

最佳答案

所以你想要这样的东西:

demo

使用自动布局设置 ScrollView 的内容大小在 Technical Note TN2154: UIScrollView And Autolayout 中有解释。 .总而言之,自动布局根据 ScrollView 及其后代 View 之间的约束设置 ScrollView 的contentSize。这意味着:

  • 您需要在 ScrollView 及其后代 View 之间创建约束,以便正确设置 ScrollView 的 contentSize

  • 您需要在图 block (图片中的彩色 View )和主视图( ScrollView 的父 View )之间创建约束以正确设置图 block 的宽度。从图 block 到其封闭 ScrollView 的约束不能设置图 block 的大小——只能设置 ScrollView 的contentSize

对于您在代码中创建的任何 View ,如果您打算使用约束来控制其大小或位置,您还需要设置translatesAutoresizingMaskIntoConstraints = false。否则,自动调整掩码会干扰您的显式约束的行为。

这是我制作演示的方法。我使用了一个 UIButton 子类,当点击它时,它会在 60 到 120 点之间切换自己的高度:

class HeightTogglingButton: UIButton {

override init(frame: CGRect) {
super.init(frame: frame)

translatesAutoresizingMaskIntoConstraints = false
heightConstraint = heightAnchor.constraint(equalToConstant: 60)
heightConstraint.isActive = true
addTarget(self, action: #selector(HeightTogglingButton.toggle(_:)), for: .touchUpInside)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

@IBAction func toggle(_ sender: Any) {
UIView.animate(withDuration: 0.3) {
self.heightConstraint.constant = 180 - self.heightConstraint.constant
self.window?.layoutIfNeeded()
}
}

private(set) var heightConstraint: NSLayoutConstraint!
}

然后我在 ScrollView 中布置了十个这样的按钮。我设置了约束来控制每个按钮的宽度,以及每个按钮相对于其他按钮的布局。顶部和底部按钮被限制在 ScrollView 的顶部和底部,因此它们控制 scrollView.contentSize.height。所有按钮都被限制在 ScrollView 的前缘和后缘,因此它们都共同控制 scrollView.contentSize.width

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)])

let margin: CGFloat = 10

var priorAnchor = scrollView.topAnchor
for i in 0 ..< 10 {
let button = HeightTogglingButton()
button.backgroundColor = UIColor(hue: CGFloat(i) / 10, saturation: 0.8, brightness: 0.3, alpha: 1)
button.setTitle("Button \(i)", for: .normal)
scrollView.addSubview(button)
NSLayoutConstraint.activate([
button.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -2 * margin),
button.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: margin),
button.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -margin),
button.topAnchor.constraint(equalTo: priorAnchor, constant: margin)])
priorAnchor = button.bottomAnchor
}

scrollView.bottomAnchor.constraint(equalTo: priorAnchor, constant: margin).isActive = true
}

}

关于ios - 使用 NSLayoutConstraints 使用 Swift 在 ScrollView 中垂直对齐动态 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40915094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com