简体   繁体   English

UIView动画在iOS 8中无法正常工作?

[英]UIView animation is not work properly in iOS 8?

I want to create animation like below, I done this in iOS 11.2. 我想创建如下动画,我在iOS 11.2中完成了此操作。

工作动画

I test this in iOS 8.4 and 9.2 - broke 我在iOS 8.4和9.2中测试了- broke

动画损坏

Storyboard 故事板

I used autoLaout 我用了autoLaout 在此处输入图片说明

RoundedShadowButton 圆形阴影按钮

I subclassed UIButton. 我将UIButton子类化。 Added RoundedCorner and DropShadow protocols to it. 向其中添加了RoundedCorner和DropShadow协议。 It contains a animateButton function that cares the animation. 它包含一个关心动画的animateButton函数。

class RoundedShadowButton: UIButton, RoundedCorner, DropShadow {
    var originalSize: CGRect?

    func animateButton(shouldLoad: Bool, withMessage message: String?) {
        let spinner = UIActivityIndicatorView()
        spinner.activityIndicatorViewStyle = .whiteLarge
        spinner.color = .darkGray
        spinner.alpha = 0.0
        spinner.hidesWhenStopped = true
        spinner.tag = 21

        if shouldLoad {
            self.addSubview(spinner)
            self.setTitle("", for: .normal)
            UIView.animate(withDuration: 0.2, animations: {
                self.setRoundedCorners(radius: self.frame.height / 2)
                self.frame = CGRect(x: self.frame.midX - (self.frame.height / 2), y: self.frame.origin.y, width: self.frame.height, height: self.frame.height)
            }, completion: { (finished) in
                if finished {
                    spinner.startAnimating()
                    spinner.center = CGPoint(x: self.frame.width / 2 + 1, y: self.frame.width / 2 + 1)
                    spinner.fadeTo(alphaValue: 1.0, withDuration: 0.2)
                }
            })
            self.isUserInteractionEnabled = false
        } else {
            self.isUserInteractionEnabled = true

            // remove spinner
            for subView in self.subviews {
                if subView.tag == 21 {
                    subView.removeFromSuperview()
                }
            }

            // return back to original button
            UIView.animate(withDuration: 0.2, animations: {
                if let size = self.originalSize {
                    self.setRoundedCorners(radius: 8)
                    self.frame = size
                    self.setTitle(message, for: .normal)
                }
            })
        }
    }
}

RoundedCorner 圆角

protocol RoundedCorner {}

extension RoundedCorner where Self: UIView {
    func setRoundedCorners(radius: CGFloat) {
        layer.cornerRadius = radius
    }
}

DropShadow 阴影

protocol DropShadow {}

extension DropShadow where Self: UIView {
    func setShadow(width: CGFloat = 0, height: CGFloat = 0, opacity: Float, radius: CGFloat, color: UIColor) {
        layer.shadowColor = color.cgColor
        layer.shadowOpacity = opacity
        layer.shadowOffset = CGSize(width: width, height: height)
        layer.shadowRadius = radius
    }
}

HomeVC 家用VC

In HomeVC's viewDidAppear, I set the corner radius, shadow and frame size. 在HomeVC的viewDidAppear中,我设置拐角半径,阴影和框架大小。 In buttons IBAction I called the animate function. 在按钮IBAction中,我调用了动画功能。

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        actionBtn.originalSize = actionBtn.frame
        actionBtn.setRoundedCorners(radius: 8)
        actionBtn.setShadow(opacity: 0.3, radius: 10.0, color: .darkGray)
    }

@IBAction func actionBtnTapped(_ sender: Any) {
        self.actionBtn.animateButton(shouldLoad: true, withMessage: nil)
    }

How to solve this? 如何解决呢?

When animating with constraints you need to work with the constraints also. 使用约束进行动画处理时,还需要使用约束。 Although it may worked sometimes, it is not something you can rely on. 尽管有时可能会起作用,但您不能依靠它。 You can solve it like this. 您可以这样解决。

  • Remove the leading and trailing constraints. 删除leadingtrailing约束。
  • Add a width constraint with same width as superview minus 40 . 添加一个宽度约束,其same widthsuperview减去40 same width Connect this to a class variable of type NSLayoutConstraint named widthConstraint . 连接这类型的类变量NSLayoutConstraint命名widthConstraint Set priority 750 . 设置优先级750
  • Add another width constraint that has width set to same as height so it becomes a circle. 添加另一个宽度约束,该约束的width设置为与高度相同,从而变为圆形。 Set priority to 500 . 将优先级设置为500
  • Add a constraint to center within superview . 将约束添加到superview center

Now, in your code replace the frame modification part. 现在,在您的代码中替换框架修改部分。

            self.frame = CGRect(x: self.frame.midX - (self.frame.height / 2), y: self.frame.origin.y, width: self.frame.height, height: self.frame.height)

With this. 有了这个。 By changing priority you choose which constraint should be in effect. 通过更改优先级,您可以选择应该生效的约束。 Since the wide constraint is at 750, it will win over the narrow constraint. 由于宽约束为750,它将克服窄约束。 When changing priority to 250, the narrow constraint will win. 将优先级更改为250时,窄约束将获胜。

            self.widthConstraint.priority = 250
            self.layoutIfNeeded()

试试这个它在我的工作结束,只需禁用此:

   self.view.translatesAutoresizingMaskIntoConstraints  = false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM