You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击视图时抖动动画出现异常问题求助

Hey there, let's figure out why your shake animation is misbehaving when tapping the view! I’ve tackled similar CA animation quirks before, so here are the most likely issues and fixes to get that shake working smoothly:

1. Your Animation Values Are Truncated (Most Likely Culprit)

Looking at your code snippet, the fromValue line cuts off with NSValue... — if you didn’t finish setting the actual x-offset values for the animation, that’s almost certainly causing the weird behavior. The fromValue and toValue need to define the left/right translation points for the shake. Here’s what that part should look like:

animation.fromValue = NSValue(cgPoint: CGPoint(x: -translation, y: 0))
animation.toValue = NSValue(cgPoint: CGPoint(x: translation, y: 0))

Without these properly set, the animation won’t know how far to move the view, leading to no movement, jitter, or erratic shakes.

2. Unremoved Old Animations Causing Overlaps

If you’re triggering the shake multiple times (like repeated taps), old animations might still be running on the view’s layer, stacking up and creating chaos. Fix this by removing any existing shake animation before adding a new one:

func shake(count: Float = 4, for duration: TimeInterval = 0.5, withTranslation translation: CGFloat = 5) {
    // Clear any existing shake animation first
    layer.removeAnimation(forKey: "shakeAnimation")
    
    let animation: CABasicAnimation = CABasicAnimation(keyPath: "transform.translation.x")
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.repeatCount = count
    animation.duration = duration / TimeInterval(animation.repeatCount)
    animation.autoreverses = true
    animation.fromValue = NSValue(cgPoint: CGPoint(x: -translation, y: 0))
    animation.toValue = NSValue(cgPoint: CGPoint(x: translation, y: 0))
    // Assign a unique key to track the animation
    layer.add(animation, forKey: "shakeAnimation")
}

3. Timing Calculation Issues

The line animation.duration = duration / TimeInterval(animation.repeatCount) splits the total duration into equal chunks for each repeat. If this results in a tiny per-repeat duration (e.g., 0.5 / 4 = 0.125 seconds), the animation can look jittery instead of smooth. Try adjusting the total duration or repeat count to get a more natural timing:

// Example tweaked parameters for smoother shakes
shake(count: 3, for: 0.6, withTranslation: 6)

4. Autoreverse & Repeat Count Misalignment

Since you have autoreverses = true, each "repeat" of the animation will play forward then backward. If your repeat count is too high, this can make the shake feel disjointed. Test lowering the count slightly (like 3 instead of 4) to see if that fixes the abnormal motion.

5. Conflicting Animations on the View

If your view has other ongoing animations (like UIView.animate blocks modifying its transform or position), these can clash with the shake animation. Make sure no other animations are running on the view when you trigger the shake.

Full Working Extension

Here’s the complete, fixed version of your extension to reference:

import UIKit

extension UIView {
    func shake(count: Float = 3, for duration: TimeInterval = 0.6, withTranslation translation: CGFloat = 6) {
        layer.removeAnimation(forKey: "shakeAnimation")
        
        let animation = CABasicAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        animation.repeatCount = count
        animation.duration = duration / TimeInterval(animation.repeatCount)
        animation.autoreverses = true
        animation.fromValue = NSValue(cgPoint: CGPoint(x: -translation, y: 0))
        animation.toValue = NSValue(cgPoint: CGPoint(x: translation, y: 0))
        
        layer.add(animation, forKey: "shakeAnimation")
    }
}

内容的提问来源于stack exchange,提问作者WBuck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:21:49