0

I've just changed my app from being TabView driven to CollectionView driven, as there are too many sections of my app to be feasible for a TabView. When you start the app you are presented with several items in a CollectionView and selecting any of these items will take you to the relevant section of the app.

In XCode, the collection view lives in its own storyboard and each section of the app has its own storyboard.

In the CollectionView's didSelectItemAtIndexPath, I launch the relevant starboard as follows;

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"relevant_storyboard" bundle:nil];
UIViewController* vc = [storyboard instantiateInitialViewController];
[self presentViewController:vc animated:YES completion:nil];

Now, none of the built-in transition animations really suit launching from a CollectionView, so I'd really like a custom effect, such as zoom in. However, I'm struggling to find any decent examples that work for me to create any kind of custom transition. I've tried [UIView transitionFromView], but I don't think that suits transitioning between UIViewControllers. I've tried transitionFromViewController:toViewController: but don't think I have the view hierarchy set up correctly. I've also tried using CATransition without success.

I've thought about doing it with a custom segue but, as my CollectionView is in it's own storyboard and have separate storyboards for each section of my app, I can't see how I can do this. At least not without having all sections of the app inside one storyboard, which would make the storyboard huge and difficult to manage.

So, can anyone give me any code examples or pointers on how I can solve this?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
swampf0etus
  • 401
  • 3
  • 10
  • I think the reason I'm struggling with this is because I don't really understand UIViewController containment. I think I need to go read up on that first. I'm also trying to watch the WWDC 2011 session 102 video that explains this, but the dev site has been down since Thursday due to hacking. Of all the WWDC videos I have downloaded, that isn't one of them. Sigh. – swampf0etus Jul 22 '13 at 10:45

2 Answers2

1

Have you tried the UIView animation block?

 [UIView animationWithDuration:1.0 animation^ {
    // do custom animation with the view
 }completion:^(BOOL finished) {
     if(finished) {
        NSLog(@"Finished");
     }
 }];

It allows you to do custom animations when dealing with UIView(s), and even with UIViewControllers. I use it alot when dealing with custom animation actions.

EDIT:

for example, if you'd like to make the view of the current controller to move up the screen, and the second view controller to slide down in place of it, just do

 [UIView animationWithDuration:1.0 animation^ {
    // do custom animation with the view
    // make sure CoreGraphics.framework is imported
    // sliding current view to the top of the screen
    self.view.transform = CGAffineTransformMakeTranslation(0,0);

    // sliding 2nd view down..
    // uncomment the following line, and one of the options for translation
    //SecondView *sv = [[SecondView alloc] init];
    // just edit the x,y in CGAffineTransformMakeTranslation to set where it will go
    //sv.view.transform = CGAffineTransformMakeTranslation(320, 480) // iphone 4
    //sv.view.transform = CGAffineTransformMakeTranslation(768, 1024) // ipad 1

 }completion:^(BOOL finished) {
     if(finished) {
        NSLog(@"Finished");
     }
 }];

Hope this helps!

user2277872
  • 2,963
  • 1
  • 21
  • 22
1

In my app I used a similar effect to zoom in from a thumbnail in a collection view cell to a child view controller that took up the entire screen. You could conceivably do the same thing for a navigation controller push as well.

In my code, I had a scoreView property on the cell subclass that I wanted to zoom up into the full screen. In your case, you may want to use a UIImageView with a screenshot of your new view. Alternatively, you could present the new view controller with a screenshot of the old view controller and then animate from there.

//Instantiate the view controller to be animated in...

//If the cell is not completely inside the collection view's frame, a dissolve animation might be more graceful.
BOOL dissolveAnimation = !CGRectContainsRect(CGRectMake(0, 0, self.collectionView.frame.size.width, self.collectionView.frame.size.height), cellRect);

//Get the frame of the cell in self.view coordinates, then the frame of the thumbnail view
CGRect cellRect = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath].frame;
cellRect = CGRectOffset(cellRect, 0.0, -self.collectionView.contentOffset.y);
VSScoreCell *scoreCell = (VSScoreCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
CGRect scoreRect = dissolveAnimation ? CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height) : CGRectMake(cellRect.origin.x + scoreCell.scoreView.frame.origin.x, cellRect.origin.y + scoreCell.scoreView.frame.origin.y, scoreCell.scoreView.frame.size.width, scoreCell.scoreView.frame.size.height);
VSScoreView *scoreView = [[VSScoreView alloc] initWithFrame:scoreRect];

//Initialize the view that will be animated up (in this case scoreView)...

if (dissolveAnimation)
    scoreView.alpha = 0.0;

[self.view addSubview:scoreView];

[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
    if (dissolveAnimation)
        scoreView.alpha = 1.0;
    else
        scoreView.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);
} completion:^(BOOL finished) {
    if (finished)
    {
        //Add scoreDisplayController as a child view controller or present it without animation
        [scoreView removeFromSuperview];            
    }
}];

Of course, the new iOS might make this easier (my lips are sealed), but I hope this is somewhat helpful for your situation!

architectpianist
  • 2,562
  • 1
  • 19
  • 27
  • I think this answer best suits the way my app currently works, i.e. the way I explained in my question. I will give this a try, however this whole question has made me think about how my app works and I think I'll be changing it. I'll still be using transition animations, though, so it's still all relevant. – swampf0etus Jul 24 '13 at 12:01