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

为何自定义Shakeable协议的shake动画不生效但print语句正常执行?

Fixing Your Shake Animation Not Working on TacoCell

Hey there! Let's break down why your shake animation isn't showing up even though the print("Shaked!") line is working. Since the print statement fires, we know your shake() method is definitely being called—so the problem lies in how the animation is set up or applied, not the method itself. Here are the most common fixes for this issue, tailored for new developers:

1. Did you forget to add the animation to the view's layer?

This is the #1 mistake new folks make with Core Animation. You can create the CABasicAnimation object all day, but if you don't add it to the view's layer, it will never run. Double-check your UIView extension code to make sure you have this critical line:

extension UIView: Shakeable {
    func shake() {
        // Create your shake animation
        let shakeAnim = CABasicAnimation(keyPath: "transform.translation.x")
        shakeAnim.fromValue = -10
        shakeAnim.toValue = 10
        shakeAnim.duration = 0.1
        shakeAnim.repeatCount = 5
        shakeAnim.autoreverses = true
        
        // THIS LINE MAKES THE ANIMATION RUN—don't skip it!
        layer.add(shakeAnim, forKey: "shakeAnimation")
        
        print("Shaked!")
    }
}

If that layer.add(...) line is missing, the animation exists but never gets attached to the cell's visual layer.

2. Verify your animation's keyPath and values are valid

Typos in the keyPath or wrong value types will silently break the animation. For example:

  • Wrong: "transform.translate.x" (it's translation, not translate)
  • Wrong: fromValue = "-10" (needs to be a numeric type like CGFloat, not a string)
    Stick to a tried-and-true shake setup like the example above first—get that working before tweaking values.

3. Make sure you're grabbing the correct cell in didSelectItemAt

Even though your print runs, it's worth confirming you're accessing the right cell instance. Your collection view delegate code should look like this:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    // Guard against nil or wrong cell type
    guard let tacoCell = collectionView.cellForItem(at: indexPath) as? TacoCell else {
        print("Couldn't cast cell to TacoCell")
        return
    }
    tacoCell.shake()
}

If the guard fails, you'd see that error print—but since your "Shaked!" line runs, this is probably okay. But it's good to rule out.

4. Check for cell reuse interfering with the animation

UICollectionView reuses cells to save memory. If you scroll the tapped cell off-screen right after tapping, the cell might get dequeued for another item, which can stop the animation mid-run. To test this:

  • Keep the tapped cell on-screen after tapping—does the animation show up then?
  • If yes, you can add a check to make sure the cell is still associated with the correct index path when animating, or temporarily disable reuse (not ideal for performance long-term, but good for testing).

5. Adjust animation properties for visibility

Sometimes the animation is running, but it's too subtle or fast to see. Try tweaking these values:

  • Increase duration to 0.2 (slower shake)
  • Increase fromValue/toValue to -15/15 (more dramatic movement)
  • Set repeatCount to 3 instead of a huge number (shorter, more noticeable shake)

Start with the first fix (adding the animation to the layer)—that's almost always the culprit when print runs but animation doesn't. Once you get that working, you can tweak the animation to your liking!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:45:46