簡體   English   中英

Swift 中 UITextField/UIView 的抖動動畫

[英]Shake Animation for UITextField/UIView in Swift

我試圖弄清楚當用戶將文本字段留空時,如何使文本字段在按下按鈕時震動。

我目前有以下代碼工作:

if self.subTotalAmountData.text == "" {

    let alertController = UIAlertController(title: "Title", message:
        "What is the Sub-Total!", preferredStyle: UIAlertControllerStyle.Alert)
    alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.Default,handler: nil))

    self.presentViewController(alertController, animated: true, completion: nil)

} else {

}

但我認為將文本字段作為警報搖晃會更有吸引力。

我找不到任何可以為文本字段設置動畫的內容。

有任何想法嗎?

謝謝!

您可以更改durationrepeatCount並對其進行調整。 這是我在我的代碼中使用的。 改變fromValuetoValue會有所不同的抖動移動的距離。

let animation = CABasicAnimation(keyPath: "position")
animation.duration = 0.07
animation.repeatCount = 4
animation.autoreverses = true
animation.fromValue = NSValue(cgPoint: CGPoint(x: viewToShake.center.x - 10, y: viewToShake.center.y))
animation.toValue = NSValue(cgPoint: CGPoint(x: viewToShake.center.x + 10, y: viewToShake.center.y))

viewToShake.layer.add(animation, forKey: "position")

以下函數用於任何視圖。

extension UIView {
    func shake() {
        let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
        animation.duration = 0.6
        animation.values = [-20.0, 20.0, -20.0, 20.0, -10.0, 10.0, -5.0, 5.0, 0.0 ]
        layer.add(animation, forKey: "shake")
    }
}

編輯:如果您連續兩次觸發動畫,使用CABasicAnimation會導致應用程序崩潰。 所以一定要使用CAKeyframeAnimation 錯誤已修復,感謝評論:)


或者,如果您想要更多參數(在 swift 5 中),您可以使用它:

public extension UIView {

    func shake(count : Float = 4,for duration : TimeInterval = 0.5,withTranslation translation : Float = 5) {

        let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
        animation.repeatCount = count
        animation.duration = duration/TimeInterval(animation.repeatCount)
        animation.autoreverses = true
        animation.values = [translation, -translation]
        layer.add(animation, forKey: "shake")
    }  
}

你可以在任何 UIView、UIButton、UILabel、UITextView 等上調用這個函數。這樣

yourView.shake()

或者,如果您想向動畫添加一些自定義參數,請使用這種方式:

yourView.shake(count: 5, for: 1.5, withTranslation: 10)

我認為所有這些都是危險的。

如果您的搖晃動畫基於用戶操作,並且該用戶操作在動畫制作時被觸發。

CRAAAAASH

這是我在Swift 4 中的方式

static func shake(view: UIView, for duration: TimeInterval = 0.5, withTranslation translation: CGFloat = 10) {
    let propertyAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.3) {
        view.transform = CGAffineTransform(translationX: translation, y: 0)
    }

    propertyAnimator.addAnimations({
        view.transform = CGAffineTransform(translationX: 0, y: 0)
    }, delayFactor: 0.2)

    propertyAnimator.startAnimation()
}

可能不是最干凈的,但是這個方法可以反復觸發,很容易理解

編輯:

我非常支持使用 UIViewPropertyAnimator。 這么多很酷的功能,讓您可以對基本動畫進行動態修改。

這是在視圖抖動時添加紅色邊框的另一個示例,然后在抖動完成時將其刪除。

static func shake(view: UIView, for duration: TimeInterval = 0.5, withTranslation translation: CGFloat = 10) {
    let propertyAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.3) {
        view.layer.borderColor = UIColor.red.cgColor
        view.layer.borderWidth = 1
        view.transform = CGAffineTransform(translationX: translation, y: 0)
    }

    propertyAnimator.addAnimations({
        view.transform = CGAffineTransform(translationX: 0, y: 0)
    }, delayFactor: 0.2)

    propertyAnimator.addCompletion { (_) in
        view.layer.borderWidth = 0
    }

    propertyAnimator.startAnimation()
}

斯威夫特 5.0

extension UIView {
    func shake(){
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.07
        animation.repeatCount = 3
        animation.autoreverses = true
        animation.fromValue = NSValue(cgPoint: CGPoint(x: self.center.x - 10, y: self.center.y))
        animation.toValue = NSValue(cgPoint: CGPoint(x: self.center.x + 10, y: self.center.y))
        self.layer.add(animation, forKey: "position")
    }
}

使用

self.vwOffer.shake()
extension CALayer {

    func shake(duration: NSTimeInterval = NSTimeInterval(0.5)) {

        let animationKey = "shake"
        removeAnimationForKey(animationKey)

        let kAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        kAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        kAnimation.duration = duration

        var needOffset = CGRectGetWidth(frame) * 0.15,
        values = [CGFloat]()

        let minOffset = needOffset * 0.1

        repeat {

            values.append(-needOffset)
            values.append(needOffset)
            needOffset *= 0.5
        } while needOffset > minOffset

        values.append(0)
        kAnimation.values = values
        addAnimation(kAnimation, forKey: animationKey)
    }
}

如何使用:

[UIView, UILabel, UITextField, UIButton & etc].layer.shake(NSTimeInterval(0.7))

斯威夫特 5

Corey Pett安全(非崩潰)震動擴展回答:

extension UIView {
    func shake(for duration: TimeInterval = 0.5, withTranslation translation: CGFloat = 10) {
        let propertyAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 0.3) {
            self.transform = CGAffineTransform(translationX: translation, y: 0)
        }

        propertyAnimator.addAnimations({
            self.transform = CGAffineTransform(translationX: 0, y: 0)
        }, delayFactor: 0.2)

        propertyAnimator.startAnimation()
    }
}

我嘗試了一些可用的解決方案,但都沒有處理完整的抖動動畫:從左向右移動並回到原始位置。

因此,經過一番調查后,我找到了正確的解決方案,我認為使用UIViewPropertyAnimator可以成功地搖一搖。

func shake(completion: (() -> Void)? = nil) {
    let speed = 0.75
    let time = 1.0 * speed - 0.15
    let timeFactor = CGFloat(time / 4)
    let animationDelays = [timeFactor, timeFactor * 2, timeFactor * 3]

    let shakeAnimator = UIViewPropertyAnimator(duration: time, dampingRatio: 0.3)
    // left, right, left, center
    shakeAnimator.addAnimations({
        self.transform = CGAffineTransform(translationX: 20, y: 0)
    })
    shakeAnimator.addAnimations({
        self.transform = CGAffineTransform(translationX: -20, y: 0)
    }, delayFactor: animationDelays[0])
    shakeAnimator.addAnimations({
        self.transform = CGAffineTransform(translationX: 20, y: 0)
    }, delayFactor: animationDelays[1])
    shakeAnimator.addAnimations({
        self.transform = CGAffineTransform(translationX: 0, y: 0)
    }, delayFactor: animationDelays[2])
    shakeAnimator.startAnimation()

    shakeAnimator.addCompletion { _ in
        completion?()
    }

    shakeAnimator.startAnimation()
}

最后結果:

搖動動畫結果

func shakeTextField(textField: UITextField)
{
    let animation = CABasicAnimation(keyPath: "position")
    animation.duration = 0.07
    animation.repeatCount = 3
    animation.autoreverses = true
    animation.fromValue = NSValue(cgPoint: CGPoint(x: textField.center.x - 10, y: textField.center.y))
    animation.toValue = NSValue(cgPoint: CGPoint(x: textField.center.x + 10, y: textField.center.y))
    textField.layer.add(animation, forKey: "position")

    textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder ?? "",
                                                         attributes: [NSAttributedStringKey.foregroundColor: UIColor.red])

}

//寫入基類或任何視圖控制器並使用它

這是基於 CABasicAnimation,它還包含一個音頻效果:

extension UIView{
    var audioPlayer = AVAudioPlayer()
    func vibrate(){
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 5.0, self.center.y))
        animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 5.0, self.center.y))
        self.layer.addAnimation(animation, forKey: "position")
        // audio part
        do {
            audioPlayer =  try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(mySoundFileName, ofType: "mp3")!))
            audioPlayer.prepareToPlay()
            audioPlayer.play()

        } catch {
            print("∙ Error playing vibrate sound..")
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM