如何为 UITableViewCell 实现抖动动画

Posted

技术标签:

【中文标题】如何为 UITableViewCell 实现抖动动画【英文标题】:How to implement a shake animation to a UITableViewCell 【发布时间】:2014-01-09 15:22:03 【问题描述】:

如何让 UITableViewCell 从左侧晃动到右侧?

我想让用户知道“这个操作是不可能的”!

【问题讨论】:

【参考方案1】:

这是我的解决方案:

    CGPoint position = cell.center;

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(position.x, position.y)];
    [path addLineToPoint:CGPointMake(position.x-20, position.y)];
    [path addLineToPoint:CGPointMake(position.x+20, position.y)];
    [path addLineToPoint:CGPointMake(position.x-20, position.y)];
    [path addLineToPoint:CGPointMake(position.x+20, position.y)];
    [path addLineToPoint:CGPointMake(position.x, position.y)];

    CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    positionAnimation.path = path.CGPath;
    positionAnimation.duration = .5f;
    positionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

    [CATransaction begin];
    [cell.layer addAnimation:positionAnimation forKey:nil];
    [CATransaction commit];

玩得开心!

【讨论】:

【参考方案2】:

谢谢汉斯一号!这里是 Swift 和 UITableViewCell 的扩展形式,可以选择持续时间和路径长度。

import UIKit
import QuartzCore

extension UITableViewCell 
    func shake(duration: CFTimeInterval = 0.3, pathLength: CGFloat = 15) 
        let position: CGPoint = self.center

        let path: UIBezierPath = UIBezierPath()
        path.moveToPoint(CGPointMake(position.x, position.y))
        path.addLineToPoint(CGPointMake(position.x-pathLength, position.y))
        path.addLineToPoint(CGPointMake(position.x+pathLength, position.y))
        path.addLineToPoint(CGPointMake(position.x-pathLength, position.y))
        path.addLineToPoint(CGPointMake(position.x+pathLength, position.y))
        path.addLineToPoint(CGPointMake(position.x, position.y))

        let positionAnimation = CAKeyframeAnimation(keyPath: "position")

        positionAnimation.path = path.CGPath
        positionAnimation.duration = duration
        positionAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)

        CATransaction.begin()
        self.layer.addAnimation(positionAnimation, forKey: nil)
        CATransaction.commit()
    

【讨论】:

【参考方案3】:

这是 oyalhi 协议的 Swift 4 版本:

import UIKit

extension UITableViewCell 
    func shake(duration: CFTimeInterval = 0.3, pathLength: CGFloat = 15) 
        let position: CGPoint = self.center

        let path: UIBezierPath = UIBezierPath()
        path.move(to: CGPoint(x: position.x, y: position.y))
        path.addLine(to: CGPoint(x: position.x-pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x+pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x-pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x+pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x, y: position.y))

        let positionAnimation = CAKeyframeAnimation(keyPath: "position")

        positionAnimation.path = path.cgPath
        positionAnimation.duration = duration
        positionAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)

        CATransaction.begin()
        self.layer.add(positionAnimation, forKey: nil)
        CATransaction.commit()
    

【讨论】:

【参考方案4】:

我根据@oyalhi 的回答用 Swift 4 创建了一个协议:

protocol Shackable  

extension Shackable where Self: UIView 

    func shake(duration: CFTimeInterval = 0.3, pathLength: CGFloat = 15) 
        let position = self.center
        let path = UIBezierPath()

        path.move(to: CGPoint(x: position.x, y: position.y))
        path.addLine(to: CGPoint(x: position.x - pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x + pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x - pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x + pathLength, y: position.y))
        path.addLine(to: CGPoint(x: position.x, y: position.y))

        let positionAnimation = CAKeyframeAnimation(keyPath: "position")
        positionAnimation.path = path.cgPath
        positionAnimation.duration = duration
        positionAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        CATransaction.begin()
        self.layer.add(positionAnimation, forKey: nil)
        CATransaction.commit()
    

【讨论】:

以上是关于如何为 UITableViewCell 实现抖动动画的主要内容,如果未能解决你的问题,请参考以下文章

如何为 UITableViewCell 设置动画

如何为 UITableViewCell 显示自定义 UIMenuItem?

如何为 UITableViewCell 的子视图禁用 UITapGesture?

如何为 UITableViewCell 的 ImageView 设置固定大小?

如何为嵌入在 UITableViewCell 中的 UIView 设置动画

如何为选择多行时使用的 UITableViewCell 图像蒙皮?