Programing

Scale UIButton 애니메이션-Swift

lottogame 2020. 11. 19. 07:46
반응형

Scale UIButton 애니메이션-Swift


UIButton클릭했을 때 스케일 애니메이션을 하려고하는데 버튼을 클릭했을 때 UIButton안쪽으로 더 작아야하고 그런 다음 같은 크기 (거품처럼)로 돌아옵니다.

다음을 시도했습니다.

button.transform = CGAffineTransformMakeScale(-1, 1)

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

    button.transform = CGAffineTransformMakeScale(1,1)

})

이 시도

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
        }
    })

SWIFT 4 코드 업데이트 : 봄 애니메이션과 함께 멋진 바운싱 효과가있는 애니메이션 버튼이 있습니다.

@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: UIViewAnimationOptions.allowUserInteraction,
                               animations: {
                                sender.transform = CGAffineTransform.identity
        },
                               completion: { Void in()  }
    )
}

위의 모든 답변이 유효합니다.
게다가 Swift 를 사용하여 원하는 뷰를 "확장"하기 위해 UIView의 확장을 만드는 것이 좋습니다.
다음 코드에서 영감을 얻을 수 있습니다.

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 duration: NSTimeInterval = 0.2) {
        self.transform = CGAffineTransformMakeScale(0.0, 0.0)
        UIView.animateWithDuration(duration, delay: 0.0, options: [.CurveLinear], animations: { () -> Void in
            self.transform = CGAffineTransformIdentity
            }) { (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 duration: NSTimeInterval = 0.2) {
        self.transform = CGAffineTransformIdentity
        UIView.animateWithDuration(duration, delay: 0.0, options: [.CurveLinear], animations: { () -> Void in
            self.transform = CGAffineTransformMakeScale(0.0, 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 duration: NSTimeInterval = 0.2, easingOffset: CGFloat = 0.2) {
        let easeScale = 1.0 + easingOffset
        let easingDuration = NSTimeInterval(easingOffset) * duration / NSTimeInterval(easeScale)
        let scalingDuration = duration - easingDuration
        UIView.animateWithDuration(scalingDuration, delay: 0.0, options: .CurveEaseIn, animations: { () -> Void in
            self.transform = CGAffineTransformMakeScale(easeScale, easeScale)
            }, completion: { (completed: Bool) -> Void in
                UIView.animateWithDuration(easingDuration, delay: 0.0, options: .CurveEaseOut, animations: { () -> Void in
                    self.transform = CGAffineTransformIdentity
                    }, completion: { (completed: Bool) -> Void in
                })
        })
    }

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

     - parameter duration:     animation duration.
     - parameter easingOffset: easing offset.
     */
    func zoomOutWithEasing(duration duration: NSTimeInterval = 0.2, easingOffset: CGFloat = 0.2) {
        let easeScale = 1.0 + easingOffset
        let easingDuration = NSTimeInterval(easingOffset) * duration / NSTimeInterval(easeScale)
        let scalingDuration = duration - easingDuration
        UIView.animateWithDuration(easingDuration, delay: 0.0, options: .CurveEaseOut, animations: { () -> Void in
            self.transform = CGAffineTransformMakeScale(easeScale, easeScale)
            }, completion: { (completed: Bool) -> Void in
                UIView.animateWithDuration(scalingDuration, delay: 0.0, options: .CurveEaseOut, animations: { () -> Void in
                    self.transform = CGAffineTransformMakeScale(0.0, 0.0)
                    }, completion: { (completed: Bool) -> Void in
                })
        })
    }

}

사용법은 매우 간단합니다.

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

Swift 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
        })
    })
}

}


Swift 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")
        }
    }

용법:

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

크레딧 : Sean Allen


Swift 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
            })
    })

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)
}

이행:

@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
}

다음과 같이 나와 함께 작동하며 애니메이션이 작게 설정되어 애니메이션을 시작하면 원래 크기로 돌아갑니다.

스위프트 2

button.transform = CGAffineTransformMakeScale(0.6, 0.6)

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

    button.transform = CGAffineTransformMakeScale(1,1)

})

스위프트 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)

})

나는 애니메이션이 끝날 때까지 기다리는 완료 컨트롤을 사용하여 다른 예보다 더 빠르게 누르기 애니메이션을 사용하고 설정하는 것을 선호합니다.

스위프트 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)
                    })
            })
    }
}

사용법 :

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

다음 애니메이션을 사용하면 버튼이 전체 크기에서 시작하여 스프링 애니메이션으로 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
             }];
            }];

iOS 9 및 xCode 7

//for zoom in
    [UIView animateWithDuration:0.5f animations:^{

        self.sendButton.transform = CGAffineTransformMakeScale(1.5, 1.5);
    } completion:^(BOOL finished){}];
// for zoom out
        [UIView animateWithDuration:0.5f animations:^{

            self.sendButton.transform = CGAffineTransformMakeScale(1, 1);
        }completion:^(BOOL finished){}];

이것은 놀라운 바운싱 효과를 줄 것입니다.

@IBAction func TouchUpInsideEvent(sender: UIButton) {
    UIView.animateWithDuration(2.0,
                               delay: 0,
                               usingSpringWithDamping: CGFloat(0.20),
                               initialSpringVelocity: CGFloat(6.0),
                               options: UIViewAnimationOptions.AllowUserInteraction,
                               animations: {
                                sender.transform = CGAffineTransformIdentity
        },
                               completion: { Void in()  }
    )
}


@IBAction func touchDownEvent(sender: UIButton) {
    UIView.animateWithDuration(0.15, animations: {
        sender.transform = CGAffineTransformMakeScale(0.6, 0.6)
    })

}

완료 핸들러를 사용하여 자동 반전 효과를 원하는 경우 이것을 시도 할 수 있습니다.

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.
        })

Scaling Button or any view about three times or more use following code. swift 3 or swift 4 with xcode 9.

 UIView.animate(withDuration: 0.2, animations: {
        self.cartShowHideBtnView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)

    }, completion: { (finish: Bool) in
            UIView.animate(withDuration: 0.2, animations: {
                self.cartShowHideBtnView.transform = CGAffineTransform.identity

            }, completion:{(finish: Bool) in
                UIView.animate(withDuration: 0.2, animations: {
                    self.cartShowHideBtnView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)

                }, completion: { (finish: Bool) in
                    UIView.animate(withDuration: 0.2, animations: {
                        self.cartShowHideBtnView.transform = CGAffineTransform.identity

                    }, completion:{(finish: Bool) in
                        UIView.animate(withDuration: 0.2, animations: {
                            self.cartShowHideBtnView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)

                        }, completion: { (finish: Bool) in
                            UIView.animate(withDuration: 0.2, animations: {
                                self.cartShowHideBtnView.transform = CGAffineTransform.identity
                        })
                    })
                })
            })
        })
    })

I did a protocol using Swift 4, that you can use at some specifics UIViews that you want to animate... You can try some animations over here or change time and delay.

This way is recommended because you can use this protocol and others at one view and this view can use this functions, doing a lot os extensions from UIView create code smell.

import Foundation
import UIKit

protocol Showable where Self: UIView {}

extension Showable {

    func show(_ view: UIView? = nil) {

        if let view = view {
            self.animate(view)
        } else {
            self.animate(self)
        }
    }

    private func animate(_ view: UIView) {
        view.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)

        UIView.animate(withDuration: 2.0,
                       delay: 0,
                       usingSpringWithDamping: CGFloat(0.20),
                       initialSpringVelocity: CGFloat(6.0),
                       options: [.allowUserInteraction],
                       animations: {
                        view.transform = CGAffineTransform.identity
        })
    }
}

Here is a working example :

extension  UIButton{
  func flash() {
    let flash = CABasicAnimation(keyPath: "opacity")
    flash.duration = 0.5
    flash.fromValue = 1
    flash.toValue = 0.1
    flash.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    flash.autoreverses = true
    flash.repeatCount = 3
    layer.add(flash, forKey: nil)
  }
}

@IBAction func taptosave(_ sender: UIButton) {
  sender.flash()
}

참고URL : https://stackoverflow.com/questions/31320819/scale-uibutton-animation-swift

반응형