我的一位同事刚刚向我展示了可用于拆分视图控制器的“替换转场”。它运作良好。
但我真的很想做从旧视图到新视图的“交叉淡入淡出”。我通过设置视图的 alpha 属性完成了淡入淡出,但不确定使用 segues 将如何工作。
我的一位同事刚刚向我展示了可用于拆分视图控制器的“替换转场”。它运作良好。
但我真的很想做从旧视图到新视图的“交叉淡入淡出”。我通过设置视图的 alpha 属性完成了淡入淡出,但不确定使用 segues 将如何工作。
问题是过渡动画需要容器视图,但是当替换拆分的细节时没有合适的容器视图,整个右侧被替换(通常使用包含细节的新导航控制器)。拆分视图有一个视图,它将两侧添加为子视图,如果每一侧都有一个容器视图,那么这将很容易。或者,您可以使用它的视图甚至窗口,但是您需要翻译框架。一种解决方法是在之前的细节控制器消失之前对其进行快照,然后将其作为子视图添加到新的细节控制器上并为其删除设置动画。这就是 Notes 实现垃圾笔记动画的方法,新笔记出现在后面(尽管它不使用 segues)。
好消息是这一切都可以在 UIStoryboardSegue 子类中完成。在 prepareForSegue 中不要设置 self.detailViewController 。在调用 super 之前的 perform 方法中,使用 sourceViewController.detailViewController 对视图进行快照。然后调用super perform。不是你可以用目的地更新那个属性(所以你下次有它)。然后将此快照添加为目的地(或其导航控制器)的子视图。CATransaction 刷新然后执行您的transitionWithView 以使用[snapshot removeFromSuperView] 为屏幕截图设置动画。这是一些示例代码:
- (void)perform{
RootViewController *rootController = self.sourceViewController;
MasterViewController *previousMasterViewController = (MasterViewController *)rootController.collapseControllerForMaster.detailViewController;
UIView *snapshotView = [previousMasterViewController.navigationController._outermostNavigationController.view snapshotViewAfterScreenUpdates:NO];
MasterViewController *masterController = (MasterViewController *)[self.destinationViewController topViewController];
rootController.collapseControllerForMaster.detailViewController = masterController;
UIView *view = [previousMasterViewController.deleteBarButtonItem valueForKey:@"view"];
CGRect rect = [view convertRect:view.frame toView:masterController.view.window];
[super perform];
[masterController.navigationController._outermostNavigationController.view addSubview:snapshotView];
[CATransaction flush];
[UIView beginAnimations:@"delete" context:NULL];
[UIView setAnimationTransition:103 forView:masterController.navigationController._outermostNavigationController.view cache:YES];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationPosition:CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect))];
[snapshotView removeFromSuperview];
[UIView commitAnimations];
}
为使用私有方法道歉,我讨厌必须重新实现关键缺失的公共方法。仅供参考,折叠控制器是我的拆分视图委托控制器对象。您也许可以只使用源控制器上的 detailViewController 属性。
这是纵向的样子:
在属性检查器中将目标视图的大小更改为“详细信息”大小。使用带有交叉溶解动画的模态转场,将转场演示大小设置为“当前上下文”。
那应该让 detailView 交叉溶解并使 masterView 不受影响。
编辑
好吧,我已经尝试了几个选项,但我的时间现在已经结束了。我想当我回来的时候你可能已经找到了答案,但这是我得到的最接近的答案。
创建一个淡出 DetailViewController 的方法,如下所示:
- (void)fadeOut
{
if (self.view.alpha > 0.0)
{
self.view.alpha = self.view.alpha - 0.01;
[self performSelector:@selector(fadeOut) withObject:nil afterDelay:0.005];
}
}
fadeOut
然后在使用 Replace segue 之前调用该方法。在新的 ViewController 中,您可以在 Replace segue 调用它时将其淡入,使用:
- (void)fadeIn
{
if (self.view.alpha > 0.0)
{
self.view.alpha = self.view.alpha + 0.01;
[self performSelector:@selector(fadeIn) withObject:nil afterDelay:0.005];
}
}
你将不得不玩弄时间,它可能看起来很奇怪(steppy and whatnot),我还没有测试出完整的概念。
以上有点骇人听闻,可能不是最好的方法,但这就是我到目前为止所拥有的。如果您还没有弄清楚,我会看看我还能做些什么并相应地进行编辑。
尝试这个: