swift 运行时UISackView设置自定义间距

ctehm74n  于 2023-01-08  发布在  Swift
关注(0)|答案(3)|浏览(366)

我有一个水平的UIStackView,默认情况下如下所示:

心脏视图最初是隐藏的,然后在运行时显示。我想减少心脏视图和帐户名称视图之间的间距。
下面的代码完成了这项工作,但 * 仅 * 在viewDidLoad中执行:

stackView.setCustomSpacing(8, after: heartView)

当以后更改自定义间距时,比如按下按钮,它不会有任何影响。现在,问题是,一旦堆栈视图中的子视图更改,自定义间距就会丢失:当从堆栈视图中取消/隐藏视图时,自定义间距被重置并且不能被修改。

的事情,我已经尝试:

  • 已验证是否通过打印stackView.customSpacing(after: heartView)(正确返回8)设置间距
  • 未成功运行多个重新加载功能:
  • stackView.layoutIfNeeded()
  • stackView.layoutSubviews()
  • view.layoutIfNeeded()
  • view.layoutSubviews()
  • viewDidLayoutSubviews()

如何在运行时更新堆栈视图的自定义间距?

ejk8hzay

ejk8hzay1#

您需要确保UIStackViewdistribution属性设置为.fill.fillProportionally
我创建了下面的swift playground,看起来我可以在运行时将setCustomSpacing与随机值一起使用,并看到效果。

import UIKit
import PlaygroundSupport

public class VC: UIViewController {

    let view1 = UIView()
    let view2 = UIView()
    let view3 = UIView()
    var stackView: UIStackView!

    public init() {
        super.init(nibName: nil, bundle: nil)
    }

    public required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    public override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        view1.backgroundColor = .red
        view2.backgroundColor = .green
        view3.backgroundColor = .blue

        view2.isHidden = true

        stackView = UIStackView(arrangedSubviews: [view1, view2, view3])
        stackView.spacing = 10
        stackView.axis = .horizontal
        stackView.distribution = .fillProportionally

        let uiSwitch = UISwitch()
        uiSwitch.addTarget(self, action: #selector(onSwitch), for: .valueChanged)

        view1.addSubview(uiSwitch)
        uiSwitch.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            uiSwitch.centerXAnchor.constraint(equalTo: view1.centerXAnchor),
            uiSwitch.centerYAnchor.constraint(equalTo: view1.centerYAnchor)
        ])

        view.addSubview(stackView)
        stackView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            stackView.heightAnchor.constraint(equalToConstant: 50),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50)
        ])
    }

    @objc public func onSwitch(sender: Any) {
        view2.isHidden = !view2.isHidden
        if !view2.isHidden {
            stackView.setCustomSpacing(CGFloat(arc4random_uniform(40)), after: view2)
        }
    }
}

PlaygroundPage.current.liveView = VC()
PlaygroundPage.current.needsIndefiniteExecution = true
ui7jx7zq

ui7jx7zq2#

setCustomSpacing可能失败的另一个原因是,如果将其称为“在添加要应用间距的已排列子视图之前”。

行不通:

headerStackView.setCustomSpacing(50, after: myLabel)
headerStackView.addArrangedSubview(myLabel)

将工作:

headerStackView.addArrangedSubview(myLabel)
headerStackView.setCustomSpacing(50, after: myLabel)
xlpyo6sf

xlpyo6sf3#

我还注意到自定义间距值在隐藏/取消隐藏子视图后会被重置。我能够覆盖父视图的updateConstraints()并根据需要设置自定义间距。视图然后保持它们预期的间距。

override func updateConstraints() {
  super.updateConstraints()
  stackView.setCustomSpacing(10, after: childView)
}

相关问题