在iOS 9上使用NavigationController进行推送动画的自定义过渡

8

我在使用UINavigationController时,为视图控制器之间创建了一个自定义的push转场效果。在iOS 7/8 上构建时,一切都工作正常,但是在针对iOS 9 SDK 构建时,会出现错误的布局。

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

  [transitionContext.containerView addSubview:toViewController.view];

  ...

然后它继续执行动画。问题在于,即使toViewController使用正确的顶部布局指南自动布局约束,其内容也会显示在导航栏后面。

尽管如此,在iOS 8上运行良好,如果我们强制重新绘制(例如,将应用程序发送到后台并将其带回,呈现模态并将其解除,等等),将导致整个自动布局系统重新绘制自己,并且toViewController的视图跳转到正确的位置(作为顶部布局指南,与设备屏幕顶部相距x像素,而不是与导航栏相距x像素)。

添加

[self.view setNeedsUpdateConstraints];
[self.view layoutIfNeeded];

该方法放在viewDidAppear:animated中可行,但是放在viewDidLoadviewWillAppear:animated中不起作用。这并不是一个解决方案,因为当重新绘制发生在viewDidAppear:animated时用户会看到视图跳动。

1个回答

24

我通过在 addSubview: 之前添加以下行来解决了我的问题:

  toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];

从Apple的文档中了解到,finalFrameForViewController:方法会返回指定视图控制器视图的结束帧矩形。

该方法返回的矩形表示过渡结束时相应视图的大小。对于在呈现期间被覆盖的视图,此方法返回的值可能是CGRectZero,但也可能是有效的帧矩形。


你刚刚为我节省了很多时间。非常感谢! - Steffen D. Sommer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接