iOS7自定义ViewController转换和顶部布局指南

ale*_*nca 25 iphone objective-c ios ios7

我在我的App中实现了一个自定义的UIViewController Transition,它取代了推送动画中内置的导航控制器.

到目前为止一切都有效,除了新推出的视图控制器中的toplayoutguide为0,尽管新视图控制器从旧视图控制器继承了导航栏.它应该是64.0(状态栏高度+导航栏高度),现在它是0.0.因此,附加到故​​事板中顶部布局指南的所有对象现在显示为64点太高(在半透明条下方).

当我禁用自定义视图转换时,顶部布局指南将具有预期值.我试图"遍布整个地方"调用layoutSubviews和updateConstraints.在视图控制器以及导航控制器中.

据我所知,navigationcontroller(parentviewcontroller)应更新新视图控制器的toplayoutguide,但显然我在自定义转换代码中遗漏了一些内容,这会触发更新为toplayoutguide的正确值.

这是我的自定义转换代码,它是一个设置为navigationcontroller委托的对象:

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.7;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIView *animationContainerView = [transitionContext containerView];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *toView = [toVC view];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *fromView = [fromVC view];

    CGRect endFrame = [transitionContext finalFrameForViewController:toVC];
    CGRect startFrame;

    startFrame = CGRectOffset(endFrame, 0, endFrame.size.height);

    if (self.operation == UINavigationControllerOperationPop) {
        [animationContainerView insertSubview:toView belowSubview:fromView];
        [toView setFrame:endFrame];
    }
    else{
        [toView setFrame:startFrame];
        [animationContainerView insertSubview:toView aboveSubview:fromView];
    }

    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 usingSpringWithDamping:0.7 initialSpringVelocity:0.8 options:UIViewAnimationOptionBeginFromCurrentState animations:^{

        if (self.operation == UINavigationControllerOperationPop) {
            [fromView setFrame:startFrame];
            [fromView layoutIfNeeded];
        }
        else{
            [toView setFrame:endFrame];
            [toView layoutIfNeeded];
        }

    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}
Run Code Online (Sandbox Code Playgroud)

没有什么真正的幻想发生在那里.只是从底部向上滑动的视图具有一些内置的动态.

问题是,附加到顶部布局指南的对象现在位于导航栏下方,因为顶部布局指南长度== 0.

我无法弄清楚我需要做什么,以便视图控制器的toplayoutguide设置为正确的值.

推送导航使用推送故事板segue执行"普通香草".在调用performSegueWithIdentifier之前,我所做的就是设置navigationcontrollers委托.

这是代码:

    self.navigationController.delegate = [[My_CustomNavigationTransitionDelegate alloc] init];
    [self performSegueWithIdentifier:@"infosSegue" sender:nil];
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

小智 5

我有一个问题,bottomLayoutGuide属性将自己设置为零长度,然后将导致我在标签栏上方的按钮低于标签栏与自动布局.

你看过这样做吗?

[self.navigationController.view setNeedsLayout]
Run Code Online (Sandbox Code Playgroud)

我把它放进了我viewwillappearbottomLayoutGuide房子里,我停止了零长度.也许这会帮助你的topLayoutGuide财产.

  • 这实际上是正确的答案,除非您必须确保实际显示视图.您必须使用viewDidAppear:方法而不是viewWillAppear:.这是因为调用此方法时将完全设置UINavigationBar(此时您的转换将仅调用完成处理程序). (2认同)

Dan*_*son 0

我可以使用以下视图层次结构来解决这个问题:

UIView
 UIScrollView
  <content, constrained to UIScrollView>
Run Code Online (Sandbox Code Playgroud)

约束 使其UIScrollView匹配UIView's顶边、前边、尾边和底边。Interface Builder 可能希望您使用 topLayoutGuide 和 BottomLayoutGuide UIScrollView,也可能不会。也许这取决于 Xcode 的版本,但我们的一些视图控制器使用了超级视图,其他视图控制器使用了布局指南。

对于 Interface Builder 不想约束滚动视图相对于其超级视图的视图,我在文本编辑器中打开情节提要,并手动调整滚动视图的约束。

最后,在视图控制器上,确保顶部栏下方的延伸边缘为“是”,“调整滚动视图插入”也是如此。

基本上,我避免使用 topLayoutGuide,而是依赖滚动视图插图,这确实有效。

我在层次结构中没有 UIScrollView 的地方,就像你一样,不在顶部栏下方延伸边缘对我有用。