简短版本:
在 iOS7 中与自定义转换和 UINavigationController
结合使用时,我遇到了自动布局顶部布局指南的问题。具体来说,顶部布局指南和 TextView 之间的约束没有得到遵守。有人遇到过这个问题吗?
长版:
我有一个场景,它具有明确定义的约束(即顶部、底部、左侧和右侧),呈现如下 View :
但是当我在导航 Controller 上使用自定义过渡时,顶部布局指南的顶部约束似乎关闭,并且呈现如下,就好像顶部布局指南位于屏幕顶部,而不是在导航 Controller 的底部:
在使用自定义转换时,导航 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
重新应用约束。我还尝试过 setNeedsUpdateConstraints
、setNeedsLayout
等。
底线,是否有人成功地将导航 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/