简体   繁体   中英

UIView animation is not work properly in iOS 8?

I want to create animation like below, I done this in iOS 11.2.

工作动画

I test this in iOS 8.4 and 9.2 - broke

动画损坏

Storyboard

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

RoundedShadowButton

I subclassed UIButton. Added RoundedCorner and DropShadow protocols to it. It contains a animateButton function that cares the animation.

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

In HomeVC's viewDidAppear, I set the corner radius, shadow and frame size. In buttons IBAction I called the animate function.

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.
  • Add a width constraint with same width as superview minus 40 . Connect this to a class variable of type NSLayoutConstraint named widthConstraint . Set priority 750 .
  • Add another width constraint that has width set to same as height so it becomes a circle. Set priority to 500 .
  • Add a constraint to center within superview .

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. When changing priority to 250, the narrow constraint will win.

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

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

   self.view.translatesAutoresizingMaskIntoConstraints  = false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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