UIViewControllers之间的自定义转换

时间:2013-07-21 19:49:37

标签: ios uiviewcontroller uiviewanimationtransition

我刚刚将我的应用程序从TabView驱动改为CollectionView驱动,因为我的应用程序有太多部分可用于TabView。当您启动应用程序时,您会在CollectionView中看到几个项目,并选择这些项目中的任何一项将带您进入应用程序的相关部分。

在XCode中,集合视图存在于自己的故事板中,应用程序的每个部分都有自己的故事板。

在CollectionView的didSelectItemAtIndexPath中,我按如下方式启动相关右舷;

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

现在,没有一个内置的过渡动画真的适合从CollectionView启动,所以我真的很喜欢自定义效果,比如放大。但是,我很难找到适合我的任何体面的例子创建任何类型的自定义转换。我已经尝试了[UIView transitionFromView],但我不认为这适合在UIViewControllers之间进行转换。我已经尝试了transitionFromViewController:toViewController:,但我认为我没有正确设置视图层次结构。我也试过使用CATransition但没有成功。

我已经考虑过使用自定义segue,但是,由于我的CollectionView位于自己的故事板中,并且我的应用程序的每个部分都有单独的故事板,我无法看到我是如何做到这一点的。至少没有将应用程序的所有部分放在一个故事板中,这会使故事板变得庞大且难以管理。

那么,任何人都可以给我任何代码示例或指示我如何解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

您是否尝试过UIView动画块?

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

它允许您在处理UIView时使用自定义动画,甚至使用UIViewControllers。在处理自定义动画操作时我会使用它。

编辑:

例如,如果您想让当前控制器的视图向上移动屏幕,而第二个视图控制器向下滑动代替它,只需执行

 [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");
     }
 }];

希望这有帮助!

答案 1 :(得分:1)

在我的应用程序中,我使用类似的效果从集合视图单元格中的缩略图放大到占据整个屏幕的子视图控制器。你可以想象,对于导航控制器推送也可以做同样的事情。

在我的代码中,我在单元子类上有一个scoreView属性,我想放大到全屏。在您的情况下,您可能希望使用UIImageView以及新视图的屏幕截图。或者,您可以使用旧视图控制器的屏幕截图显示新视图控制器,然后从那里进行动画处理。

//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];            
    }
}];

当然,新的iOS可能会让这更容易(我的嘴唇是密封的),但我希望这对你的情况有所帮助!

相关问题