29

I have created a UICollectionView and would like to have all the cells shake like the edit mode of the springboard on the iPhone. I have created my shake code but don't know how to implement it. I have custom cells so I assume it goes in there but don't know how it gets implemented. Thank You.

#define degreesToRadians(x) (M_PI * (x) / 180.0)
#define kAnimationRotateDeg 0.5
#define kAnimationTranslateX 1.0
#define kAnimationTranslateY 1.0

//startJiggling

int count = 1;
CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? +1 : -1 ) ));
CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? -1 : +1 ) ));
CGAffineTransform moveTransform = CGAffineTransformTranslate(rightWobble, -kAnimationTranslateX, -kAnimationTranslateY);
CGAffineTransform conCatTransform = CGAffineTransformConcat(rightWobble, moveTransform);

    self.transform = leftWobble;  // starting point

    [UIView animateWithDuration:0.1
                          delay:(count * 0.08)
                        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
                     animations:^{ self.transform = conCatTransform; }
                     completion:nil];
BDGapps
  • 3,318
  • 10
  • 56
  • 75

5 Answers5

14

If you put you're code in a method called startJiggling in your custom cell, then you could call this method in your controller:

[self.collectionView.visibleCells makeObjectsPerformSelector:@selector(startJiggling)];

That ensures that all visible cells will start jiggling.

Then I'd also set some flag indicating that your cells should jiggle and test for that in collectionView:cellForItemAtIndexPath:. If YES, then call your method.

fguchelaar
  • 4,779
  • 23
  • 36
  • Great except all but the last cell is shaking. when i print out the visible cell count and the array count its off by 1. the visible cell count is lower. Any ideas? NSLog(@"visibleCellscount %d",self.collectionView.visibleCells.count); NSLog(@"birdscount %d",self.birds.count); – BDGapps Dec 24 '12 at 23:40
  • But all cells áre visible? Or do you have to scroll for the last one? – fguchelaar Dec 25 '12 at 22:14
7

Swift 5 Easy like this

Enter this 2 functions to your UICollectionViewCell and call it when ever you want to animate/stop, ex: cell render

func shake() {
    let shakeAnimation = CABasicAnimation(keyPath: "transform.rotation")
    shakeAnimation.duration = 0.05
    shakeAnimation.repeatCount = 2
    shakeAnimation.autoreverses = true
    let startAngle: Float = (-2) * 3.14159/180
    let stopAngle = -startAngle
    shakeAnimation.fromValue = NSNumber(value: startAngle as Float)
    shakeAnimation.toValue = NSNumber(value: 3 * stopAngle as Float)
    shakeAnimation.autoreverses = true
    shakeAnimation.duration = 0.15
    shakeAnimation.repeatCount = 10000
    shakeAnimation.timeOffset = 290 * drand48()

    let layer: CALayer = self.layer
    layer.add(shakeAnimation, forKey:"shaking")
}

func stopShaking() {
    let layer: CALayer = self.layer
    layer.removeAnimation(forKey: "shaking")
}

Help Source from Git

Lahiru Pinto
  • 1,621
  • 19
  • 20
4

If anyone is curious on how to do this in Swift 2.0 the below should be a good starting point.

let animationRotateDegres: CGFloat = 0.5
let animationTranslateX: CGFloat = 1.0
let animationTranslateY: CGFloat = 1.0
let count: Int = 1

func wobble() {
    let leftOrRight: CGFloat = (count % 2 == 0 ? 1 : -1)
    let rightOrLeft: CGFloat = (count % 2 == 0 ? -1 : 1)
    let leftWobble: CGAffineTransform = CGAffineTransformMakeRotation(degreesToRadians(animationRotateDegres * leftOrRight))
    let rightWobble: CGAffineTransform = CGAffineTransformMakeRotation(degreesToRadians(animationRotateDegres * rightOrLeft))
    let moveTransform: CGAffineTransform = CGAffineTransformTranslate(leftWobble, -animationTranslateX, -animationTranslateY)
    let conCatTransform: CGAffineTransform = CGAffineTransformConcat(leftWobble, moveTransform)

    transform = rightWobble // starting point

    UIView.animateWithDuration(0.1, delay: 0.08, options: [.AllowUserInteraction, .Repeat, .Autoreverse], animations: { () -> Void in
        self.transform = conCatTransform
        }, completion: nil)
}

func degreesToRadians(x: CGFloat) -> CGFloat {
    return CGFloat(M_PI) * x / 180.0
}

When I want to make my cells wobble I do so like this:

for cell in collectionView.visibleCells() {
        let customCell: MyCustomCell = cell as! MyCustomCell
        customCell.wobble()
    }
Xeaza
  • 1,410
  • 1
  • 17
  • 21
3

Updated to swift 3 syntax:

let animationRotateDegres: CGFloat = 0.5
let animationTranslateX: CGFloat = 1.0
let animationTranslateY: CGFloat = 1.0
let count: Int = 1

func wobble() {
    let leftOrRight: CGFloat = (count % 2 == 0 ? 1 : -1)
    let rightOrLeft: CGFloat = (count % 2 == 0 ? -1 : 1)
    let leftWobble: CGAffineTransform = CGAffineTransform(rotationAngle: degreesToRadians(x: animationRotateDegres * leftOrRight))
    let rightWobble: CGAffineTransform = CGAffineTransform(rotationAngle: degreesToRadians(x: animationRotateDegres * rightOrLeft))
    let moveTransform: CGAffineTransform = leftWobble.translatedBy(x: -animationTranslateX, y: -animationTranslateY)
    let conCatTransform: CGAffineTransform = leftWobble.concatenating(moveTransform)

    transform = rightWobble // starting point

    UIView.animate(withDuration: 0.1, delay: 0.08, options: [.allowUserInteraction, .autoreverse], animations: { () -> Void in
        self.transform = conCatTransform
    }, completion: nil)
}

func degreesToRadians(x: CGFloat) -> CGFloat {
    return CGFloat(M_PI) * x / 180.0
}
user12345625
  • 398
  • 6
  • 17
1

Place this line of code at two places:

[self.collectionView.visibleCells makeObjectsPerformSelector:@selector(startJiggling)];    
  1. -(void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath

  2. -(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView

Izuka
  • 2,572
  • 5
  • 29
  • 34