【问题标题】:Custom transition between UIViewControllersUIViewControllers 之间的自定义转换
【发布时间】:2013-07-20 12:26:16
【问题描述】:

我刚刚将我的应用程序从 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 位于它自己的故事板中,并且我的应用程序的每个部分都有单独的故事板,所以我不知道该怎么做。至少在没有将应用程序的所有部分都放在一个故事板中的情况下,这会使故事板变得庞大且难以管理。

那么,谁能给我任何代码示例或指示我如何解决这个问题?

【问题讨论】:

  • 我认为我为此苦苦挣扎的原因是因为我并不真正了解 UIViewController 的遏制。我想我需要先阅读一下。我也在尝试观看解释这一点的 WWDC 2011 session 102 视频,但由于黑客攻击,开发网站自周四以来一直处于关闭状态。在我下载的所有 WWDC 视频中,这不是其中之一。叹息。

标签: ios uiviewcontroller uiviewanimationtransition


【解决方案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 可能会让这更容易(我的嘴唇是密封的),但我希望这对你的情况有所帮助!

【讨论】:

  • 我认为这个答案最适合我的应用程序当前的工作方式,即我在问题中解释的方式。我会试一试,但是整个问题让我思考我的应用程序是如何工作的,我想我会改变它。不过,我仍然会使用过渡动画,所以它仍然是相关的。
【解决方案2】:

你试过 UIView 动画块吗?

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

它允许您在处理 UIView(s) 甚至 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");
     }
 }];

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 2014-02-02
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多