繁体   English   中英

如何使用自动布局约束来调整和定位嵌入式 UIViewController?

[英]How to size and position an embedded UIViewController using Auto Layout constraints?

这是我想要做的:我的故事板包含一个UIViewController和几个UIViewController 它的高度不到半个屏幕。 为简单起见,我们称其为DataViewController DataViewController通过“ Container View ”嵌入到其他UIViewControllers

尽管“ Container View ”显示了DataViewController ,它仍然需要有一个明确的height设置。 否则界面构建器会抱怨不明确的约束。

现在,我如何告诉“ Container View ”它的大小应该是DataViewController所需的大小? 即没有在 Interface Builder 中设置硬编码的显式height (我担心,如果字体大小改变,会破坏布局)?

或者换句话说:如何在 Interface Builder 中调整嵌入式UIViewControllers大小/位置?

如果您希望 childViewContainer 负责其宽度和高度,这里有一种方法:

  • 在父视图控制器中设置宽度和高度约束,并在构建时选择删除。 它们就在这里,因此界面构建器不再抱怨缺少约束。 在此处输入图片说明

  • (您可以)在故事板大小检查器选项卡中将子视图控制器模拟大小从固定更改为自由格式。

在此处输入图片说明

  • 这是技巧:在您的父视图控制器中,viewDidLoad 在第一个子视图上禁用 translatesAutoresizingMaskIntoConstraints,然后自己重​​新定义其子视图的 containerView 约束 - 子视图控制器的根视图 - 如下所示:

目标-C

- (void)viewDidLoad {
    [super viewDidLoad];
    self.containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = NO;
}

#pragma mark - Constraints

- (void)updateViewConstraints {
    [super updateViewConstraints];
    [self initConstraints];
}

- (void)initConstraints {
    if (!self.didSetConstraints) {
        self.didSetConstraints = YES;

        self.containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = NO;

        NSDictionary *views = @{@"subview" : self.containerView.subviews[0]};

        [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview]|" options:0 metrics:nil views:views]];
        [self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview]|" options:0 metrics:nil views:views]];
    }
}

斯威夫特

override func viewDidLoad() {
    super.viewDidLoad()
    containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = false
}

// Mark: Constraints

override func updateViewConstraints() {
    super.updateViewConstraints()
    initConstraints()
}

func initConstraints() {
    if !didSetConstraints {
        didSetConstraints = true

        containerView.subviews[0].translatesAutoresizingMaskIntoConstraints = false

        let views = ["subview": containerView.subviews[0]]

        containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[subview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
        containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[subview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
    }
}

现在您的子视图控制器(链接到容器视图)对其内容大小负全部责任。 因此,您必须设置约束,让根视图计算其大小以满足它所持有的约束。

如果您使用 segue 嵌入,只需执行以下操作:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let viewController = segue.destination as? EmbeddedViewController {
      viewController.view.translatesAutoresizingMaskIntoConstraints = false
    }
}

在您的内容视图控制器中设置preferredContentSize (在您的示例DataViewController ),如下所示

override func viewDidLoad() {
    super.viewDidLoad()
    preferredContentSize = CGSize(width: 400, height: 200)
}

当孩子被添加到 parentViewController 时,parentViewController 会收到有关首选大小的通知。 在父级上调用以下函数

func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer)

在此方法中,您可以将容器更改为孩子的首选大小。
例如将高度更改为子/内容的首选高度

override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
    // heightConstraint is a IBOutlet to your NSLayoutConstraint you want to adapt to height of your content
    heigtConstraint.constant = container.preferredContentSize.height
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM