uinavigationcontroller - 导航 Controller 顶部布局指南不支持自定义过渡

标签 uinavigationcontroller ios7 autolayout custom-transition

简短版本:

在 iOS7 中与自定义转换和 UINavigationController 结合使用时,我遇到了自动布局顶部布局指南的问题。具体来说,顶部布局指南和 TextView 之间的约束没有得到遵守。有人遇到过这个问题吗?

<小时/>

长版:

我有一个场景,它具有明确定义的约束(即顶部、底部、左侧和右侧),呈现如下 View :

right

但是当我在导航 Controller 上使用自定义过渡时,顶部布局指南的顶部约束似乎关闭,并且呈现如下,就好像顶部布局指南位于屏幕顶部,而不是在导航 Controller 的底部:

wrong

在使用自定义转换时,导航 Controller 的“顶部布局指南”似乎会变得困惑。其余约束均已正确应用。如果我旋转设备并再次旋转它,一切都会突然正确渲染,因此约束定义不正确似乎不是问题。同样,当我关闭自定义过渡时, View 会正确渲染。

话虽如此,当我运行时,_autolayoutTrace 报告 UILayoutGuide 对象遭受 AMBIGUOUS LAYOUT 的影响:

(lldb) po [[UIWindow keyWindow] _autolayoutTrace]

但是,每当我查看这些布局指南时,它们总是被报告为不明确,即使我已经确保不存在缺失的约束(我已经完成了 View Controller 的常规选择并选择“为 View Controller 添加缺失的约束”或者选择所有控件并对它们执行相同的操作)。

就我进行转换的精确程度而言,我在 animationControllerForOperation 方法中指定了一个符合 UIViewControllerAnimatedTransitioning 的对象:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController*)fromVC
                                                 toViewController:(UIViewController*)toVC
{
    if (operation == UINavigationControllerOperationPush)
        return [[PushAnimator alloc] init];

    return nil;
}

还有

@implementation PushAnimator

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

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

    [[transitionContext containerView] addSubview:toViewController.view];
    CGFloat width = fromViewController.view.frame.size.width;

    toViewController.view.transform = CGAffineTransformMakeTranslation(width, 0);

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromViewController.view.transform = CGAffineTransformMakeTranslation(-width / 2.0, 0);
        toViewController.view.transform = CGAffineTransformIdentity;
    } completion:^(BOOL finished) {
        fromViewController.view.transform = CGAffineTransformIdentity;
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

我还对上述内容进行了演绎,设置了 View 的frame而不是transform,得到了相同的结果。

我还尝试手动确保通过调用 layoutIfNeeded 重新应用约束。我还尝试过 setNeedsUpdateConstraintssetNeedsLayout 等。

底线,是否有人成功地将导航 Controller 的自定义转换与使用顶部布局指南的约束结合起来?

最佳答案

通过添加此行设法解决我的问题:

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

致:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView {

    // Add the toView to the container
    UIView* containerView = [transitionContext containerView];
    [containerView addSubview:toView];
    [containerView sendSubviewToBack:toView];


    // animate
    toVC.view.frame = [transitionContext finalFrameForViewController:toVC];
    NSTimeInterval duration = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:duration animations:^{
        fromView.alpha = 0.0;
    } completion:^(BOOL finished) {
        if ([transitionContext transitionWasCancelled]) {
            fromView.alpha = 1.0;
        } else {
            // reset from- view to its original state
            [fromView removeFromSuperview];
            fromView.alpha = 1.0;
        }
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];

}

来自 Apple 的 [finalFrameForViewController] 文档:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewControllerContextTransitioning_protocol/#//apple_ref/occ/intfm/UIViewControllerContextTransitioning/finalFrameForViewController :

关于uinavigationcontroller - 导航 Controller 顶部布局指南不支持自定义过渡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20312765/

相关文章:

ios - Swift:以编程方式为 subview 设置自动布局约束不调整 View 大小

IOS - 替换 NavController 中的初始 View

ios - 嵌入自定义容器 View Controller 时,内容位于导航栏下方。

ios - 修改约束

ios - 使用自动布局的 UITextView 动态高度 - 每行新行的文本截断顶行

ios7 - 在 ios7 中为 UIBarButtonItem 应用边框

ios - 删除 uinavigationbar 标题边距

iphone - 如何在没有任何透明/淡入淡出效果的情况下执行 kCATransitionPush 动画

ios - 应用程序中的两个选项卡 Controller

ios - 如何将 UIView 对象添加到 ios7 中的 self.view.window?