簡體   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