简体   繁体   English

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

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

Here is what I wanna do: My storyboard contains a UIViewController with just a few controlls.这是我想要做的:我的故事板包含一个UIViewController和几个UIViewController It's height is less than half a screen.它的高度不到半个屏幕。 For simplicity, let's call it the DataViewController .为简单起见,我们称其为DataViewController The DataViewController is embedded inside other UIViewControllers through a " Container View ". DataViewController通过“ Container View ”嵌入到其他UIViewControllers

Although " Container View " displays the DataViewController , it still needs to have an explicit height set.尽管“ Container View ”显示了DataViewController ,它仍然需要有一个明确的height设置。 Otherwise interface builder complains about ambiguous constraints.否则界面构建器会抱怨不明确的约束。

Now, how can I tell " Container View " that it's size should be what's required by DataViewController ?现在,我如何告诉“ Container View ”它的大小应该是DataViewController所需的大小? Ie without setting a hard coded, explicit height in Interface Builder (which, I fear, would break the layout if the font size changes)?即没有在 Interface Builder 中设置硬编码的显式height (我担心,如果字体大小改变,会破坏布局)?

Or in other words: How do you size/position embedded UIViewControllers in Interface Builder?或者换句话说:如何在 Interface Builder 中调整嵌入式UIViewControllers大小/位置?

If you want the childViewContainer to be responsible for its width and height, here is a way to do it :如果您希望 childViewContainer 负责其宽度和高度,这里有一种方法:

  • Set width and height constraints in your Parent View Controller(s) and select remove at build time.在父视图控制器中设置宽度和高度约束,并在构建时选择删除。 They are just here so interface builder stops complaining about missing constraints.它们就在这里,因此界面构建器不再抱怨缺少约束。 在此处输入图片说明

  • (You can) Change your Child View Controller simulated size from fixed to freeform in your storyboard size inspector tab. (您可以)在故事板大小检查器选项卡中将子视图控制器模拟大小从固定更改为自由格式。

在此处输入图片说明

  • Here is the trick : In your Parent View Controller(s) viewDidLoad disable translatesAutoresizingMaskIntoConstraints on the first subviews, and simply redefine by yourself the containerView constraints to its subview - root view of your Child View Controller - like bellow :这是技巧:在您的父视图控制器中,viewDidLoad 在第一个子视图上禁用 translatesAutoresizingMaskIntoConstraints,然后自己重​​新定义其子视图的 containerView 约束 - 子视图控制器的根视图 - 如下所示:

Objective-C目标-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]];
    }
}

Swift斯威夫特

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))
    }
}

Now your child View Controller (linked to the container view) is fully responsible for its content size.现在您的子视图控制器(链接到容器视图)对其内容大小负全部责任。 Thus, you must set constraints that let the root view calculates its size to satisfies the constraints it holds.因此,您必须设置约束,让根视图计算其大小以满足它所持有的约束。

If you are embedding with a segue, just do:如果您使用 segue 嵌入,只需执行以下操作:

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

in your content view controller set the preferredContentSize (In your example DataViewController ) like the following在您的内容视图控制器中设置preferredContentSize (在您的示例DataViewController ),如下所示

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

When the child gets added to the parentViewController, the parentViewController gets notified about the prefered size.当孩子被添加到 parentViewController 时,parentViewController 会收到有关首选大小的通知。 Following function gets called on the parent在父级上调用以下函数

func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer)

In this method you can then change the container to the prefered size of the child.在此方法中,您可以将容器更改为孩子的首选大小。
For example change the height to the prefered height of the child/content例如将高度更改为子/内容的首选高度

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.

相关问题 通过自动布局和约束更改位置 - Change position with auto layout and constraints 使用自动布局约束动态调整表视图单元格的大小 - Dynamically size Table View Cells using Auto Layout constraints 如何使用“自动布局”约束将2个具有可变大小的标签放入表格单元格中,该表格单元格的高度是使用EstimateHeightForRowAtIndexPath估算的 - How to use Auto Layout constraints to fit 2 labels with variable size in a table cell which height is estimated using estimatedHeightForRowAtIndexPath 如何在其他UIViewController中设置UIViewController的位置和大小 - How to set position and size of UIViewController in other UIViewController 如何在iOS中使用自动布局时在运行时更改UIViewController中的组件 - how to change components in UIViewController on runtime while using auto layout in iOS 不了解自动布局,约束和尺寸类别 - Not understanding auto layout, constraints and size classes 来自内部内容大小的自动布局约束 - Auto layout constraints from intrinsic content size 如何使用自动版面更改标签位置 - How to change Label position using Auto layout 使用 constraintEqualToAnchor() 时如何在设置自动布局约束后更改它们? - How to change Auto Layout constraints after they are set when using constraintEqualToAnchor()? UIViewController中的UIsearchController使用自动布局 - UIsearchController inside UIViewController using Auto Layout
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM