在UIStackView中自定义比例间距,而不需要额外的子视图吗?

huangapple go评论69阅读模式
英文:

Custom proportional spacing in UIStackView without of additional subviews?

问题

我知道可以将透明的子视图添加到UIStackView中,并使用约束设置它们的宽度。问题是,如果我想隐藏一些不透明的子视图,它们之间的间距仍然存在(我不知道如何正确地“禁用”这些间距)。

我找到了setCustomSpacing(_:after:)方法:

https://developer.apple.com/documentation/uikit/uistackview/2866023-setcustomspacing

问题是它设置的是固定的间距,而在我的情况下,不透明的子视图具有固定的宽度,它们之间的间距是变化的。

然后我找到了customSpacing(after:)方法,并尝试重写它:

https://developer.apple.com/documentation/uikit/uistackview/2865827-customspacing

这似乎是我最合适的解决方案,但问题是重写的方法从未被调用。

那么,有没有一种正常的方法可以在UIStackView中添加具有比例间距的子视图,并允许同时隐藏这些子视图及其间距?

英文:

I know that I can add transparent subviews to UIStackView and set their widths with constraints. The problem is if I want to hide some opaque subviews all the spaces between them remain (and I don't know how to "disable" these spaces properly).

I found setCustomSpacing(_:after:):

https://developer.apple.com/documentation/uikit/uistackview/2866023-setcustomspacing

The problem is it sets constant spacing but in my case opaque subviews have constant width and spacing between them varies.

Then I found customSpacing(after:) and tried to override it:

https://developer.apple.com/documentation/uikit/uistackview/2865827-customspacing

It seems to be the most appropriate solution for me but the problem is the overriden method is never called.

So are there normal ways to add subviews into UIStackView with proportional spacing and allow to hide these subviews simultaneously with their spacing?

答案1

得分: 0

如果您的间距根据其他视图的尺寸动态变化,请在layoutSubviewsviewDidLayoutSubviews中设置间距。这些方法将在某个视图的尺寸发生变化时调用。在这里,您可以进行任何您喜欢的计算,并为每个视图的间距计算一个值。

例如,这里我创建了一个包含3个标签的堆栈视图。第一个标签和第二个标签之间的间距等于堆栈视图宽度的1/10,第二个标签和第三个标签之间的间距等于堆栈视图宽度的1/20(即第一个间距的一半)。

var stack: UIStackView!

override func viewDidLoad() {
    func makeLabel(_ text: String) -> UILabel {
        let label = UILabel(frame: .zero)
        label.text = text
        label.backgroundColor = .green
        label.sizeToFit()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }
    stack = UIStackView(arrangedSubviews: [makeLabel("Foo Bar"), makeLabel("Something"), makeLabel("Else")])
    stack.axis = .horizontal
    stack.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(stack)
    NSLayoutConstraint.activate([
        view.centerYAnchor.constraint(equalTo: stack.centerYAnchor),
        stack.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10),
        stack.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10)
    ])
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    stack.setCustomSpacing(stack.bounds.width / 10, after: stack.arrangedSubviews[0])
    stack.setCustomSpacing(stack.bounds.width / 20, after: stack.arrangedSubviews[1])
}
英文:

If your spacings varies dynamically, depending on the dimensions of other views, set the spacings in layoutSubviews, or viewDidLayoutSubviews if you are in a VC. These are the methods that will be called when some view's dimensions change. There, you can do whatever calculations you like, and compute a value for each view's spacing.

For example, here I have created a stack view with 3 labels. The spacing between the first and second labels is equal to 1/10 of the stack view's width, and the spacing between the second and third labels is equal to 1/20 of the stack view's width (aka one half of the first).

var stack: UIStackView!

override func viewDidLoad() {
    func makeLabel(_ text: String) -> UILabel {
        let label = UILabel(frame: .zero)
        label.text = text
        label.backgroundColor = .green
        label.sizeToFit()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }
    stack = UIStackView(arrangedSubviews: [makeLabel("Foo Bar"), makeLabel("Something"), makeLabel("Else")])
    stack.axis = .horizontal
    stack.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(stack)
    NSLayoutConstraint.activate([
        view.centerYAnchor.constraint(equalTo: stack.centerYAnchor),
        stack.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10),
        stack.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10)
    ])
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    stack.setCustomSpacing(stack.bounds.width / 10, after: stack.arrangedSubviews[0])
    stack.setCustomSpacing(stack.bounds.width / 20, after: stack.arrangedSubviews[1])
}

huangapple
  • 本文由 发表于 2023年7月27日 16:04:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定