1

I want to present a child view controller by dropping it from top to the bottom. The child view controller is a UICollectionViewController with several cells in it. I can use the iOS7 UIViewControllerContextTransitioning for the dropping down view controller transition. But if I want only the collection view to bounce (like a ball hit on the ground) when the child view controller is presented, how should I do?

I have try to use UIKit Dynamics and create some UIAnimatorBehavior on the UICollectionView after the transition, like UIGravityBehavior and UIPushBehavior. But they don't seem to work. Maybe I am using them in the wrong way. Is there anyone can give me some hints?

illustration of view controllers

Update

After tried several solutions, I finally came out a solution which is pretty close to what I want. This video shows the result: http://youtu.be/tueXDBMsdt0

But I think there should be a better solution for that. And here is my solution's steps:

  1. Create a UIViewControllerAnimatedTransitioning object, which animate the view controller transition from top to bottom.

  2. The child view controller is a UICollectionViewController. At the end of transition animation, I set child view controller's scrollview content offset to (0, -30), and then complete the transition.

  3. In child view controller's viewDidAppear, animate the content offset back to (0, 0).

  4. Besides, I also follow the instructions in the article: http://www.teehanlax.com/blog/implementing-a-bouncy-uicollectionviewlayout-with-uikit-dynamics/ to set UIKit dynamics animator in cells. When the content offset is changed, then the cells will look like bouncing.

The transition animation code looks like this:

- (void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
  UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

  CGRect frame = [[transitionContext containerView] frame];
  CGRect startFrame = frame;
  startFrame.origin.y -= CGRectGetHeight(transitionContext.containerView.frame);

  [transitionContext.containerView addSubview:fromViewController.view];
  [transitionContext.containerView addSubview:toViewController.view];
  toViewController.view.frame = startFrame;

  [UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{

                 toViewController.view.frame = frame;
               }
               completion:^(BOOL finished) {
                 ((UICollectionViewController*)toViewController).contentOffset = CGPointMake(0, -30);
                 [transitionContext completeTransition:YES];
               }];
}

And in child view controller viewDidAppear:

- (void) viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];

  [self.collectionView setContentOffset:CGPointMake(0, 0) animated:YES];
}

But I would still want the cell to bounce more naturally. Any other better solutions?

tshepang
  • 12,111
  • 21
  • 91
  • 136
syshen
  • 397
  • 3
  • 13
  • Don't forget this super-simple solution in iOS7 ...... http://stackoverflow.com/a/23514653/294884 – Fattie Jun 10 '14 at 06:56

1 Answers1

2

Important: this can now be done in iOS in one simple line of code:

https://stackoverflow.com/a/23514653/294884

Detailed answer when fuller control is needed:


If you want the same effect between the Screen lock and the Camera on the iPhone, you can use UIViewControllerContextTransitioning

enter image description here

There are a good tutorial here http://www.objc.io/issue-5/view-controller-transitions.html and here http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/

if you have a Apple developer account, there are a video about View controller transition : https://developer.apple.com/tech-talks/videos/

The video is named "Architecting Modern Apps, Part 1"

This way work only on iOS7!

Community
  • 1
  • 1
VivienCormier
  • 1,133
  • 1
  • 11
  • 16
  • This is not what I want. I don't want to bounce the view controller, I just want to bounce the UICollectionView inside the view controller. – syshen Jan 09 '14 at 15:43
  • 1
    @syshen you can apply the same effect to any subview of a UIViewController. Check the links provided. The interaction is always between `UIDynamics` and `UIView` property of `UIViewController`, and not, of course, between `UIDynamics` and `UIViewController` – art-divin Jan 09 '14 at 17:37
  • Great informative answer, which I gave a bounty to, **BUT READERS SHOULD REALISE YOU CAN DO THIS IN ONE LINE OF CODE NOW** .. stackoverflow.com/a/23514653/294884 Cheers all! – Fattie Jun 11 '14 at 09:25