【问题标题】:AutoLayout won't resize view when rotating in a custom container view?在自定义容器视图中旋转时 AutoLayout 不会调整视图大小?
【发布时间】:2012-11-01 12:38:25
【问题描述】:

我有一个非常基本的容器视图,它包含一个侧边栏并在内容区域中交换视图控制器(想想 UISplitView,但带有一个小图标侧边栏/垂直 UITabBar)。

容器视图控制器使用自动布局并在旋转时正确调整大小。 Content viewController 1 使用自动布局并且是用 IB 制作的,所以它有一个 xib 文件。 Content viewController 2 继承自 UITableViewController,不使用 xib。

如果我将 viewController 1 指定为根视图控制器并旋转,则调整大小会起作用,这是我在 viewController 1 中获得的回调:

  • willRotateToInterfaceOrientation
  • 更新视图约束
  • viewWillLayoutSubviews
  • didRotateFromInterfaceOrientation

但是,如果我将容器视图控制器指定为根视图控制器,加载 viewController 1 并旋转,则调整大小不起作用。而且我只在 viewController 1 中得到以下回调:

  • willRotateToInterfaceOrientation
  • didRotateFromInterfaceOrientation

在我的视图控制器容器中,我是这样交换视图控制器的:

[self addChildViewController:toViewController];
[toViewController didMoveToParentViewController:self];

// Remove the old view controller
[fromViewController willMoveToParentViewController:nil];
[fromViewController.view removeFromSuperview];
[fromViewController removeFromParentViewController];

// Add the new view
[self.contentContainerView addSubview:toViewController.view];

现在,我确实收到了轮换即将发生的回调,但似乎既没有调用 updateViewConstraints 也没有调用 viewWillLayoutSubviews。这解释了为什么没有发生调整大小,但是为什么一旦我将视图控制器放入容器视图中就不会调用这些方法?

我还尝试在我的容器中显式返回 YES

shouldAutomaticallyForwardAppearanceMethods

shouldAutomaticallyForwardAppearanceMethods

虽然这应该已经是默认设置了。

另外,不是用 IB 制作的视图控制器(视图控制器 2)在容器内旋转时会正确调整大小。但是,我没有在这个上明确使用 NSLayoutConstraints,所以我怀疑它默认使用 Springs 和 Struts 来调整旋转时的大小。

我是否需要在我的视图控制器容器上转发一些其他事件以使自动布局视图控制器在旋转时正确调整大小?

【问题讨论】:

    标签: objective-c ios autolayout


    【解决方案1】:

    好的,我想我的视图控制器容器中缺少这个方法:

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        self.contentViewController.view.frame = self.contentContainerView.bounds;
    }
    

    虽然现在旋转时可以正确调整大小,但它仍然不会触发

    updateViewConstraints
    

    在我的子视图控制器中。有趣

    【讨论】:

    • 使用一些日志记录,看起来超级视图的方向变化没有传递给孩子。我正在使用情节提要,IB 不允许我更改视图或向顶层视图添加约束。添加这个对我有用: - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { self.view.frame = self.view.superview.bounds; }
    • 奇怪,我有一个模态显示的视图控制器,除了这个技巧没有任何效果......确实很有趣。
    【解决方案2】:

    似乎 iOS 8 确实为您调用了 updateViewConstraints。但 iOS 7 没有。要在 iOS 7 中调用它,请调用 setNeedsUpdateConstraints,如下所示:

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
    {
        [super willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration];
    
        BOOL isiOS7 = floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1;
        if (isiOS7) {
            // Trigger a call to updateViewConstraints
            [self.view setNeedsUpdateConstraints];
        }
    }
    

    在 updateLayoutConstraints 中,检查哪个方向是布局的一个好方法是检查状态栏的方向。这适用于 7 和 8。

    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    BOOL layoutAsLandscape = UIInterfaceOrientationIsLandscape(orientation);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 2012-06-29
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多