UIStackView анимирует слева, когда isHidden == true - PullRequest
0 голосов
/ 07 октября 2019

У меня есть UIStackView с кучей упорядоченных подпредставлений. Я хочу, чтобы все они были скрыты в viewDidLoad, поэтому я иду и делаю

public func setStackViewHidden(_ isHidden: Bool, animated: Bool) {
    stackView.arrangedSubviews.forEach ({ subview in
        if animated {
            UIView.animate(withDuration: 0.3) {
                subview.isHidden = isHidden
            }
        } else {
            subview.isHidden = isHidden
        }
    })
}

Это делает весь стек ViewView скрытым. Когда я тогда иду и использую тот же метод с isHidden == false. Он анимируется слева и расширяется вправо до нужного размера. Почему он не анимируется от правильной ширины к низу, а скорее от левого к целому размеру?

1 Ответ

0 голосов
/ 09 октября 2019

Встроенная анимация UIStackView используется, когда упорядоченное подпредставление показано / скрыто, может работать хорошо - и это может быть не так уж и хорошо.

Одна из ключевых вещей, связанных с представлением стекаdo is организовать свои подпредставления . Конечно, часто также используют ширину и высоту подпредставлений, чтобы определить ширину и высоту стекового представления. Таким образом, мы можем получить неопределенные состояния, и анимация, как вы видели, становится «вонючей».

Дайте этому попытку (весь код, не @IBOutlets или @IBActions, поэтому просто назначьтеконтроллер представления к этому классу):

class StackShowHideViewController: UIViewController {

    // UIButton
    let btn: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Tap Me", for: .normal)
        v.backgroundColor = .red
        return v
    }()

    // vertical UIStackView
    let stackView: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .vertical
        v.alignment = .fill
        v.distribution = .fill
        v.spacing = 8
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        // add elements to view
        view.addSubview(btn)
        view.addSubview(stackView)

        NSLayoutConstraint.activate([

            // constrain button 20-pts from top, centered horizontally
            btn.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            btn.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            // constrain stack view 20-pts from bottom of button
            // centered horizontally
            // width constrained to 160-pts
            stackView.topAnchor.constraint(equalTo: btn.bottomAnchor, constant: 20.0),
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.widthAnchor.constraint(equalToConstant: 160.0),

        ])

        // add 5 UILabels to the stack view
        for i in 1...5 {
            let v = UILabel()
            v.backgroundColor = .yellow
            v.text = "This is Label \(i)"
            v.textAlignment = .center
            v.translatesAutoresizingMaskIntoConstraints = false
            // inititially hidden
            v.isHidden = true
            // add label to stack view
            stackView.addArrangedSubview(v)
            // constrain label widths to width of stack view
            v.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true
        }

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)

    }

    public func setStackViewHidden(_ isHidden: Bool, animated: Bool) {
        stackView.arrangedSubviews.forEach ({ subview in
            if animated {
                UIView.animate(withDuration: 0.3) {
                    subview.isHidden = isHidden
                }
            } else {
                subview.isHidden = isHidden
            }
        })
    }

    @objc func didTap(_ sender: Any) {
        // if labels are hidden, show them
        // else, hide them
        var h = true
        if let v = stackView.arrangedSubviews.first {
            h = v.isHidden
        }
        setStackViewHidden(!h, animated: true)
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...