Reputation: 1514
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
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)
}
})
}
}
}
protocol RoundedCorner {}
extension RoundedCorner where Self: UIView {
func setRoundedCorners(radius: CGFloat) {
layer.cornerRadius = radius
}
}
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
}
}
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?
Upvotes: 0
Views: 92
Reputation: 961
Try this its working at my end simply disable this :
self.view.translatesAutoresizingMaskIntoConstraints = false
Upvotes: 0
Reputation: 4323
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.
leading
and trailing
constraints.same width
as superview
minus 40
. Connect this to a class variable of type NSLayoutConstraint
named widthConstraint
. Set priority 750
.width
set to same as height so it becomes a circle. Set priority to 500
.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()
Upvotes: 2