如何为子视图控制器设置 topLayoutGuide 位置 [英] How to set topLayoutGuide position for child view controller

查看:18
本文介绍了如何为子视图控制器设置 topLayoutGuide 位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个自定义容器,它与 UINavigationController 非常相似,只是它不包含整个控制器堆栈.它有一个 UINavigationBar,它被约束到容器控制器的 topLayoutGuide,它恰好离顶部 20px,这是可以的.

I'm implementing a custom container which is pretty similar to UINavigationController except for it does not hold the whole controller stack. It has a UINavigationBar which is constrained to the container controller's topLayoutGuide, which happens to be 20px off the top, which is OK.

当我添加一个子视图控制器并将其视图放入层次结构时,我希望它的 topLayoutGuide 在 IB 中看到并用于布置子视图控制器的视图的子视图,以显示在我的导航栏底部.相关文档中有说明要做什么:

When I add a child view controller and put its view into the hierarchy I want its topLayoutGuide seen in IB and used for laying out the child view controller's view's subviews to appear at the bottom of my navigation bar. There is a note of what is to be done in the relevant documentation:

这个属性的值,具体来说就是长度的值查询此属性时返回的对象的属性.这值受视图控制器或其封闭的约束容器视图控制器(例如导航或标签栏控制器),如下:

The value of this property is, specifically, the value of the length property of the object returned when you query this property. This value is constrained by either the view controller or by its enclosing container view controller (such as a navigation or tab bar controller), as follows:

  • 不在容器视图控制器内的视图控制器限制此属性以指示状态栏的底部(如果可见),
    或者指示视图控制器视图的顶部边缘.
  • 容器视图控制器中的视图控制器不会设置此属性的值.相反,容器视图控制器约束值以指示:
    • 导航栏的底部,如果导航栏可见
    • 状态栏的底部,如果只有状态栏可见
    • 视图控制器视图的顶部边缘,如果状态栏和导航栏都不可见

    但我不太明白如何约束它的值",因为 topLayoutGuide 和它的长度属性都是只读的.

    But I don't quite understand how to "constrain it's value" since both the topLayoutGuide and it's length properties are readonly.

    我已经尝试使用此代码添加子视图控制器:

    I've tried this code for adding a child view controller:

    [self addChildViewController:gamePhaseController];
    UIView *gamePhaseControllerView = gamePhaseController.view;
    gamePhaseControllerView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentContainer addSubview:gamePhaseControllerView];
    
    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-0-[gamePhaseControllerView]-0-|"
                                                                             options:0
                                                                             metrics:nil
                                                                               views:NSDictionaryOfVariableBindings(gamePhaseControllerView)];
    
    NSLayoutConstraint *topLayoutGuideConstraint = [NSLayoutConstraint constraintWithItem:gamePhaseController.topLayoutGuide
                                                                                attribute:NSLayoutAttributeTop
                                                                                relatedBy:NSLayoutRelationEqual
                                                                                   toItem:self.navigationBar
                                                                                attribute:NSLayoutAttributeBottom
                                                                               multiplier:1 constant:0];
    NSLayoutConstraint *bottomLayoutGuideConstraint = [NSLayoutConstraint constraintWithItem:gamePhaseController.bottomLayoutGuide
                                                                                   attribute:NSLayoutAttributeBottom
                                                                                   relatedBy:NSLayoutRelationEqual
                                                                                      toItem:self.bottomLayoutGuide
                                                                                   attribute:NSLayoutAttributeTop
                                                                                  multiplier:1 constant:0];
    [self.view addConstraint:topLayoutGuideConstraint];
    [self.view addConstraint:bottomLayoutGuideConstraint];
    [self.contentContainer addConstraints:horizontalConstraints];
    [gamePhaseController didMoveToParentViewController:self];
    
    _contentController = gamePhaseController;
    

    在 IB 中,我为 gamePhaseController 指定了Under Top Bars"和Under Bottom Bars".其中一个视图被明确限制在顶部布局指南中,无论如何在设备上它似乎离容器导航栏底部 20 像素......

    In the IB I specify "Under Top Bars" and "Under Bottom Bars" for the gamePhaseController. One of the views is specifically constrained to the top layout guide, anyway on the device it appears to be 20px off the the bottom of the container's navigation bar...

    实现具有这种行为的自定义容器控制器的正确方法是什么?

    What is the right way of implementing a custom container controller with this behavior?

    推荐答案

    据我经过数小时调试后得知,布局指南是只读的,并且派生自用于基于约束的布局的私有类.覆盖访问器没有任何作用(即使它们被调用),而且这一切都非常烦人.

    As far as I have been able to tell after hours of debugging, the layout guides are readonly, and derived from the private classes used for constraints based layout. Overriding the accessors does nothing (even though they are called), and it's all just craptastically annoying.

    这篇关于如何为子视图控制器设置 topLayoutGuide 位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆