ios 缩放 UIButton 动画 - Swift

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31320819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 06:48:34  来源:igfitidea点击:

Scale UIButton Animation- Swift

iosswiftcgaffinetransformscale

提问by AaoIi

I'm trying to do scale animation for UIButtonwhen its clicked but what I'm trying to accomplish is when the button clicked I need the UIButtonto be smaller to the inside then it comes back to its same size (like a bubble).

我正在尝试UIButton在点击时进行缩放动画,但我想要完成的是当点击按钮时,我需要将UIButton其缩小到内部,然后它会恢复到相同的大小(如气泡)。

I tried the following:

我尝试了以下方法:

button.transform = CGAffineTransformMakeScale(-1, 1)

UIView.animateWithDuration(0.5, animations: { () -> Void in

    button.transform = CGAffineTransformMakeScale(1,1)

})

回答by nRewik

Try this

尝试这个

UIView.animate(withDuration: 0.6,
    animations: {
        self.button.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
    },
    completion: { _ in
        UIView.animate(withDuration: 0.6) {
            self.button.transform = CGAffineTransform.identity
        }
    })

回答by ViJay Avhad

SWIFT 5 Code Update:I have animated button with a nice bouncing effect , with spring animation.

SWIFT 5 代码更新:我有一个具有很好弹跳效果的动画按钮,带有弹簧动画。

@IBOutlet weak var button: UIButton!

@IBAction func animateButton(sender: UIButton) {

    sender.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)

    UIView.animate(withDuration: 2.0,
                               delay: 0,
                               usingSpringWithDamping: CGFloat(0.20),
                               initialSpringVelocity: CGFloat(6.0),
                               options: UIView.AnimationOptions.allowUserInteraction,
                               animations: {
                                sender.transform = CGAffineTransform.identity
        },
                               completion: { Void in()  }
    )
}

回答by Luca Davanzo

All of the answers above are valid.
As a plus, with SwiftI suggest to create an extension of UIView in order to "scale" any view you want.
You can take inspiration from this piece of code:

以上所有答案都是有效的。
作为一个加号,我建议使用Swift创建 UIView 的扩展,以便“缩放”您想要的任何视图。
你可以从这段代码中获得灵感:

SWIFT 5.0

斯威夫特 5.0

extension UIView {

/**
 Simply zooming in of a view: set view scale to 0 and zoom to Identity on 'duration' time interval.

 - parameter duration: animation duration
 */
func zoomIn(duration: TimeInterval = 0.2) {
    self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
    UIView.animate(withDuration: duration, delay: 0.0, options: [.curveLinear], animations: { () -> Void in
        self.transform = .identity
        }) { (animationCompleted: Bool) -> Void in
    }
}

/**
 Simply zooming out of a view: set view scale to Identity and zoom out to 0 on 'duration' time interval.

 - parameter duration: animation duration
 */
func zoomOut(duration : TimeInterval = 0.2) {
    self.transform = .identity
    UIView.animate(withDuration: duration, delay: 0.0, options: [.curveLinear], animations: { () -> Void in
        self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
        }) { (animationCompleted: Bool) -> Void in
    }
}

/**
 Zoom in any view with specified offset magnification.

 - parameter duration:     animation duration.
 - parameter easingOffset: easing offset.
 */
func zoomInWithEasing(duration: TimeInterval = 0.2, easingOffset: CGFloat = 0.2) {
    let easeScale = 1.0 + easingOffset
    let easingDuration = TimeInterval(easingOffset) * duration / TimeInterval(easeScale)
    let scalingDuration = duration - easingDuration
    UIView.animate(withDuration: scalingDuration, delay: 0.0, options: .curveEaseIn, animations: { () -> Void in
        self.transform = CGAffineTransform(scaleX: easeScale, y: easeScale)
        }, completion: { (completed: Bool) -> Void in
            UIView.animate(withDuration: easingDuration, delay: 0.0, options: .curveEaseOut, animations: { () -> Void in
                self.transform = .identity
                }, completion: { (completed: Bool) -> Void in
            })
    })
}

/**
 Zoom out any view with specified offset magnification.

 - parameter duration:     animation duration.
 - parameter easingOffset: easing offset.
 */
func zoomOutWithEasing(duration: TimeInterval = 0.2, easingOffset: CGFloat = 0.2) {
    let easeScale = 1.0 + easingOffset
    let easingDuration = TimeInterval(easingOffset) * duration / TimeInterval(easeScale)
    let scalingDuration = duration - easingDuration
    UIView.animate(withDuration: easingDuration, delay: 0.0, options: .curveEaseOut, animations: { () -> Void in
        self.transform = CGAffineTransform(scaleX: easeScale, y: easeScale)
        }, completion: { (completed: Bool) -> Void in
            UIView.animate(withDuration: scalingDuration, delay: 0.0, options: .curveEaseOut, animations: { () -> Void in
                self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
                }, completion: { (completed: Bool) -> Void in
            })
    })
}

}

Usage is very simply:

用法很简单:

let button = UIButton(frame: frame)
button.zoomIn() // here the magic

Swift 3 Version

斯威夫特 3 版本

extension UIView {

/**
 Simply zooming in of a view: set view scale to 0 and zoom to Identity on 'duration' time interval.

 - parameter duration: animation duration
 */
func zoomIn(duration: TimeInterval = 0.2) {
    self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
    UIView.animate(withDuration: duration, delay: 0.0, options: [.curveLinear], animations: { () -> Void in
        self.transform = CGAffineTransform.identity
    }) { (animationCompleted: Bool) -> Void in
    }
}

/**
 Simply zooming out of a view: set view scale to Identity and zoom out to 0 on 'duration' time interval.

 - parameter duration: animation duration
 */
func zoomOut(duration: TimeInterval = 0.2) {
    self.transform = CGAffineTransform.identity
    UIView.animate(withDuration: duration, delay: 0.0, options: [.curveLinear], animations: { () -> Void in
        self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
    }) { (animationCompleted: Bool) -> Void in
    }
}

/**
 Zoom in any view with specified offset magnification.

 - parameter duration:     animation duration.
 - parameter easingOffset: easing offset.
 */
func zoomInWithEasing(duration: TimeInterval = 0.2, easingOffset: CGFloat = 0.2) {
    let easeScale = 1.0 + easingOffset
    let easingDuration = TimeInterval(easingOffset) * duration / TimeInterval(easeScale)
    let scalingDuration = duration - easingDuration
    UIView.animate(withDuration: scalingDuration, delay: 0.0, options: .curveEaseIn, animations: { () -> Void in
        self.transform = CGAffineTransform(scaleX: easeScale, y: easeScale)
    }, completion: { (completed: Bool) -> Void in
        UIView.animate(withDuration: easingDuration, delay: 0.0, options: .curveEaseOut, animations: { () -> Void in
            self.transform = CGAffineTransform.identity
        }, completion: { (completed: Bool) -> Void in
        })
    })
}

/**
 Zoom out any view with specified offset magnification.

 - parameter duration:     animation duration.
 - parameter easingOffset: easing offset.
 */
func zoomOutWithEasing(duration: TimeInterval = 0.2, easingOffset: CGFloat = 0.2) {
    let easeScale = 1.0 + easingOffset
    let easingDuration = TimeInterval(easingOffset) * duration / TimeInterval(easeScale)
    let scalingDuration = duration - easingDuration
    UIView.animate(withDuration: easingDuration, delay: 0.0, options: .curveEaseOut, animations: { () -> Void in
        self.transform = CGAffineTransform(scaleX: easeScale, y: easeScale)
    }, completion: { (completed: Bool) -> Void in
        UIView.animate(withDuration: scalingDuration, delay: 0.0, options: .curveEaseOut, animations: { () -> Void in
            self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
        }, completion: { (completed: Bool) -> Void in
        })
    })
}

}

回答by Hemang

Swift 3.x+

斯威夫特 3.x+

extension UIButton {

        func pulsate() {

            let pulse = CASpringAnimation(keyPath: "transform.scale")
            pulse.duration = 0.2
            pulse.fromValue = 0.95
            pulse.toValue = 1.0
            pulse.autoreverses = true
            pulse.repeatCount = 2
            pulse.initialVelocity = 0.5
            pulse.damping = 1.0

            layer.add(pulse, forKey: "pulse")
        }

        func flash() {

            let flash = CABasicAnimation(keyPath: "opacity")
            flash.duration = 0.2
            flash.fromValue = 1
            flash.toValue = 0.1
            flash.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            flash.autoreverses = true
            flash.repeatCount = 3

            layer.add(flash, forKey: nil)
        }


        func shake() {

            let shake = CABasicAnimation(keyPath: "position")
            shake.duration = 0.05
            shake.repeatCount = 2
            shake.autoreverses = true

            let fromPoint = CGPoint(x: center.x - 5, y: center.y)
            let fromValue = NSValue(cgPoint: fromPoint)

            let toPoint = CGPoint(x: center.x + 5, y: center.y)
            let toValue = NSValue(cgPoint: toPoint)

            shake.fromValue = fromValue
            shake.toValue = toValue

            layer.add(shake, forKey: "position")
        }
    }

Usage:

用法:

myButton.flash()
// myButton.pulsate()
// myButton.shake()

Credits: Sean Allen

学分:肖恩艾伦

回答by funkenstrahlen

Swift 3 Version:

斯威夫特 3 版本:

    UIView.animate(withDuration: 0.6, animations: {
        button.transform = CGAffineTransform.identity.scaledBy(x: 0.6, y: 0.6)
        }, completion: { (finish) in
            UIView.animate(withDuration: 0.6, animations: {
                button.transform = CGAffineTransform.identity
            })
    })

回答by AaoIi

It works with me as following, the animation is set to be small then when it start animation it get back to its original size:

它与我一起工作如下,动画设置为小然后当它开始动画时它会恢复到原来的大小:

Swift 2

斯威夫特 2

button.transform = CGAffineTransformMakeScale(0.6, 0.6)

UIView.animateWithDuration(0.3, animations: { () -> Void in

    button.transform = CGAffineTransformMakeScale(1,1)

})

Swift 3, 4, 5

斯威夫特 3、4、5

button.transform = CGAffineTransform.init(scaleX: 0.6, y: 0.6)

UIView.animate(withDuration: 0.3, animations: { () -> Void in

    button.transform = CGAffineTransform.init(scaleX: 1, y: 1)

})

回答by rbaldwin

Using Swift 4 Xcode 9, This will animate the button down when initially pressed and then back up when released.

使用Swift 4 Xcode 9,这将使按钮在最初按下时向下动画,然后在释放时返回。

extension UIView {

func animateButtonDown() {

    UIView.animate(withDuration: 0.1, delay: 0.0, options: [.allowUserInteraction, .curveEaseIn], animations: {
        self.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
    }, completion: nil)
}

func animateButtonUp() {

    UIView.animate(withDuration: 0.1, delay: 0.0, options: [.allowUserInteraction, .curveEaseOut], animations: {
        self.transform = CGAffineTransform.identity
    }, completion: nil)
}

Implementation:

执行:

@IBAction func buttonTouchDown(_ sender: UIButton) {
    //Connected with Touch Down Action
    sender.animateButtonDown()
}

@IBAction func buttonTouchUpOutside(_ sender: UIButton) {
    //Connected with Touch Up Outside Action
    //if touch moved away from button
    sender.animateButtonUp()
}

@IBAction func buttonTouchUpInside(_ sender: UIButton) {
    //Connected with Touch Up Inside Action
    sender.animateButtonUp()
    //code to execute when button pressed
}

回答by Alessandro Ornano

I prefer to have the press animation and set it more fast than the other examples, with the completion control for waiting until the animation is ended:

我更喜欢使用按下动画并将其设置得比其他示例更快,并使用完成控件等待动画结束:

Swift 3:

斯威夫特 3

extension UIButton {
   func press(completion:@escaping ((Bool) -> Void)) {
            UIView.animate(withDuration: 0.05, animations: {
                self.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) }, completion: { (finish: Bool) in
                    UIView.animate(withDuration: 0.1, animations: {
                        self.transform = CGAffineTransform.identity
                        completion(finish)
                    })
            })
    }
}

Usage:

用法

@IBAction func playPauseBtnTap(_ sender: Any) {
     let playPauseBtn = sender as! UIButton
     playPauseBtn.press(completion:{ finish in
         if finish {
             print("animation ended")
         }
     }
}

回答by Khaled Zayed

Using the following animation the button will start from its full size, decrease to 0.6 with a spring animation to bounce back to it's full size.

使用以下动画,按钮将从其全尺寸开始,减少到 0.6 并使用弹簧动画反弹回其全尺寸。

[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.4 initialSpringVelocity:0.3 options:0 animations:^{
                //Animations
                button.transform = CGAffineTransformIdentity;
                CGAffineTransformMakeScale(0.6, 0.6)
            } completion:^(BOOL finished) {
                //Completion Block
            [UIView.animateWithDuration(0.5){
            button.transform = CGAffineTransformIdentity
             }];
            }];

回答by Kunal Verma

You can try this if you want a Autoreverse effect with a completion handler.

如果你想要一个带有完成处理程序的 Autoreverse 效果,你可以试试这个。

viewToAnimate.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
        UIView.animate(withDuration: 0.7, // your duration
                       delay: 0,
                       usingSpringWithDamping: 0.2,
                       initialSpringVelocity: 6.0,
                       animations: { _ in
                       viewToAnimate.transform = .identity
            },
                       completion: { _ in
                        // Implement your awesome logic here.
        })