子视图控制器中的topLayoutGuide

hpi*_*que 69 uiviewcontroller ios uipageviewcontroller autolayout ios7

我有一个UIPageViewController半透明的状态栏和导航栏.topLayoutGuide正如预期的那样,它是64像素.

但是,UIPageViewController报告的子视图控制器为topLayoutGuide0像素,即使它们显示在状态栏和导航栏下.

这是预期的行为吗?如果是这样,在真实情况下定位子视图控制器视图的最佳方法是topLayoutGuide什么?

(缺少使用parentViewController.topLayoutGuide,我认为是黑客攻击)

Nac*_*oto 48

虽然这个答案可能是正确的,但我仍然发现自己不得不前往收容树找到合适的父视图控制器并获得你所描述的"真实topLayoutGuide".这种方式我可以手动实现automaticallyAdjustsScrollViewInsets.

这就是我这样做的方式:

在我的表视图控制器(UIViewController实际的子类)中,我有这个:

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    _tableView.frame = self.view.bounds;

    const UIEdgeInsets insets = (self.automaticallyAdjustsScrollViewInsets) ? UIEdgeInsetsMake(self.ms_navigationBarTopLayoutGuide.length,
                                                                                               0.0,
                                                                                               self.ms_navigationBarBottomLayoutGuide.length,
                                                                                               0.0) : UIEdgeInsetsZero;
    _tableView.contentInset = _tableView.scrollIndicatorInsets = insets;
}
Run Code Online (Sandbox Code Playgroud)

注意类别方法UIViewController,这是我实现它们的方式:

@implementation UIViewController (MSLayoutSupport)

- (id<UILayoutSupport>)ms_navigationBarTopLayoutGuide {
    if (self.parentViewController &&
        ![self.parentViewController isKindOfClass:UINavigationController.class]) {
        return self.parentViewController.ms_navigationBarTopLayoutGuide;
    } else {
        return self.topLayoutGuide;
    }
}

- (id<UILayoutSupport>)ms_navigationBarBottomLayoutGuide {
    if (self.parentViewController &&
        ![self.parentViewController isKindOfClass:UINavigationController.class]) {
        return self.parentViewController.ms_navigationBarBottomLayoutGuide;
    } else {
        return self.bottomLayoutGuide;
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :)

  • 谢谢.我不得不添加一个`[_ tableView setContentOffset:CGPointMake(0,0 - _tableView.contentInset.top)animated:NO];`让它正确滚动到顶部 (2认同)

chl*_*iul 11

您可以在故事板中添加约束并在viewWillLayoutSubviews中更改它

这样的事情:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    self.topGuideConstraint.constant = [self.parentViewController.topLayoutGuide length];
}
Run Code Online (Sandbox Code Playgroud)


vin*_*aut 10

我可能错了,但在我看来这种行为是正确的.容器视图控制器可以使用topLayout值来布局其视图的子视图.

参考文献说:

要在不使用约束的情况下使用顶部布局指南,请获取指南相对于包含视图顶部边界的位置.

在父级中,相对于包含视图,该值将为64.

在子节点中,相对于包含视图(父节点),值将为0.

在容器View Controller中,您可以通过以下方式使用该属性:

- (void) viewWillLayoutSubviews {

    CGRect viewBounds = self.view.bounds;
    CGFloat topBarOffset = self.topLayoutGuide.length;

    for (UIView *view in [self.view subviews]){
        view.frame = CGRectMake(viewBounds.origin.x, viewBounds.origin.y+topBarOffset, viewBounds.size.width, viewBounds.size.height-topBarOffset);
    }
}
Run Code Online (Sandbox Code Playgroud)

子视图控制器不需要知道存在导航和状态栏:其父级已经将其考虑在内的子视图.

如果我创建一个新的基于页面的项目,将其嵌入导航控制器,并将此代码添加到父视图控制器,它似乎工作正常:

在此输入图像描述

  • 但是如果子视图控制器是`UIScrollView`子类,如果你设置这样的框架,你就不会得到半透明导航栏下显示的内容的效果,这就是拥有半透明导航栏的全部目的.第一名. (19认同)

Cor*_*uff 8

文档说如果您使用的是UIViewController子类,则在viewDidLayoutSubviews中使用topLayoutGuide,如果您使用的是UIView子类,则使用layoutSubviews.

如果在这些方法中使用它,则应获得适当的非零值.

文档链接:https: //developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/topLayoutGuide