UIView 动画只工作一次而不工作

问题描述 投票:0回答:2

我尝试为我的视图做一个动画,但如果只是第一次工作,即 isOpen = true 它可以工作,但当我再次调用我的函数 isOpen = false 时没有任何变化?

父视图是自身(UIView)。孩子是标签(UILabel)。

private func expansionView(isOpen: Bool) {
        if isOpen {
            label.backgroundColor = .white
            NSLayoutConstraint.activate([
                 label.centerYAnchor.constraint(equalTo: self.topAnchor),
                 label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15),
             ])
            
            UIView.animate(withDuration: 1, animations: {
                self.layoutIfNeeded()
            }) { (_) in
                
            }
        } else {
            label.backgroundColor = .clear
            NSLayoutConstraint.activate([
                 label.centerYAnchor.constraint(equalTo: self.centerYAnchor),
                 label.leadingAnchor.constraint(equalTo: self.leadingAnchor , constant: 15),
             ])

            UIView.animate(withDuration: 1, animations: {
                self.layoutIfNeeded()
            }) { (_) in
                print("Animation Completed!!!")
            }
        }
    }
swift animation layout constraints
2个回答
1
投票

您需要有两个约束才能使其中之一处于活动状态。 您还可以通过动画将标签的背景颜色更改为透明。您可以像下面这样简化您的功能。

// define both vertical constraints
var constraintToCenterYAnchor: NSLayoutConstraint!
var constraintToTopAnchor: NSLayoutConstraint!

// where you init your view..
init() {
    // init your constraints
    constraintToTopAnchor = label.centerYAnchor.constraint(equalTo: topAnchor)
    constraintToCenterYAnchor = label.centerYAnchor.constraint(equalTo: centerYAnchor)

    // set and activate other constraints once.
    label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15).isActive = true

    // update background color of the label
    label.backgroundColor = .clear
    label.layer.backgroundColor = UIColor.white.cgColor
}

// simplify your function
private func expansionView(_ isOpen: Bool) {
    constraintToTopAnchor.isActive = isOpen
    constraintToCenterYAnchor.isActive = !isOpen
    
    UIView.animate(withDuration: 1) {
        self.label.layer.opacity = isOpen ? 1.0 : 0.0
        self.layoutIfNeeded()
    }
}

1
投票

您需要有两个约束来激活和停用...

lazy var centerXConstraint = label.centerYAnchor.constraint(equalTo: self.centerYAnchor)
lazy var topConstraint = label.leadingAnchor.constraint(equalTo: self.leadingAnchor , constant: 15)
    
    
    init() {
        label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15).isActive = true
    }
    private func expansionView(isOpen: Bool) {
        if isOpen {
            label.backgroundColor = .white
            
            centerXConstraint.isActive = false
            topConstraint.isActive = true
            
            UIView.animate(withDuration: 1, animations: {
                self.layoutIfNeeded()
            }) { (_) in
                
            }
        } else {
            label.backgroundColor = .clear
            
              centerXConstraint.isActive = true
              topConstraint.isActive = false
            UIView.animate(withDuration: 1, animations: {
                self.layoutIfNeeded()
            }) { (_) in
                print("Animation Completed!!!")
            }
        }
        
    }
© www.soinside.com 2019 - 2024. All rights reserved.