gpt4 book ai didi

ios - 在将 View 添加到 View 树之前如何计算 UIViewController 高度?

转载 作者:行者123 更新时间:2023-11-28 23:34:16 27 4
gpt4 key购买 nike

我需要测量给定宽度的基于简单自动布局的 VC 的高度。 例如一个简单的UIViewController,只有一个标签,该标签使用VC Root View 的前导、尾随、顶部和底部约束进行定位。 VC 应该具有固定大小,而是自动适应标签内容。

这只是一个例子,当然VC可以有其他影响大小的内容。

如何在不将给定宽度和标签内容添加到 View 层次结构的情况下计算 VC 大小?

背景:

我正在使用第三方 FormSheet 控件,它可以轻松地将任何 ViewController 显示为具有不同样式、过渡等的表单。唯一的缺点是,必须指定固定的表单大小在展示 VC 之前。

虽然这对于具有“静态”内容/固定大小的 VC 非常有效,但即使是针对不同语言使用不同文本的标签也可能会破坏设计。

因此我正在寻找这样的东西:

ContentViewController *contentVC = [ContentViewController new];
CGRect contentBounds = [SomeClass calculateAutoLayoutHeightForView:contentVC.view withFixedWidth:500];

[ThirPartyFormSheetController presentController:contentVC withSize:contentBounds];

如何做到这一点?

最佳答案

给定一个宽度,您可以使用 systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 来确定自动布局完成后的高度。

假设 view-to-show 中的约束设置正确:

CGFloat w = 500.0;
[loadedView.widthAnchor constraintEqualToConstant:w].active = YES;

// caluclate the size using FittingCompressedSize
CGSize contentBounds = [loadedView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

这是一个简单的示例(只需要将 ViewController 类分配给 Storyboard 中的 View Controller ...不需要 IBOutlets)。代码中的大量注释应该使一切都清楚:

//
// ViewController.h
// Created by Don Mag on 4/8/19.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

//
// ViewController.m
// Created by Don Mag on 4/8/19.
//

#import "ViewController.h"
#import "FormViewController.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// add a button we'll use to show the form VC
UIButton *b = [UIButton new];
b.translatesAutoresizingMaskIntoConstraints = NO;
[b setTitle:@"Show Form" forState:UIControlStateNormal];
[b setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[b setBackgroundColor:[UIColor redColor]];

[self.view addSubview:b];

[NSLayoutConstraint activateConstraints:
@[
[b.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:20.0],
[b.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:0.75],
[b.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor]
]
];

[b addTarget:self action:@selector(loadAndShowForm:) forControlEvents:UIControlEventTouchUpInside];

}

- (void) loadAndShowForm:(id)sender {

// instantiate the form view controller
FormViewController *vc = [FormViewController new];

// get a reference to its view
UIView *v = vc.view;

// use auto-layout
v.translatesAutoresizingMaskIntoConstraints = NO;

// set the label text in the form view
vc.topLabel.text = @"This is a bunch of text for the TOP label in the Form VC";
vc.bottomLabel.text = @"This is a bunch of text for the BOTTOM label in the Form VC. It's enough text to cause a few lines of word-wrap, assuming we're running on an iPhone.";

// specify a width for the form view
// we'll use width of current view minus 60 (30-pts on each side)
CGFloat w = self.view.frame.size.width - 60.0;
[v.widthAnchor constraintEqualToConstant:w].active = YES;

// caluclate the size using FittingCompressedSize
CGSize contentBounds = [v systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

// because we set the width constraint, we now have the "compressed" height
//[ThirdPartyFormSheetController presentController:contentVC withSize:contentBounds];

// debugging from here down
NSLog(@"Auto-layout resulting size: %@", [NSValue valueWithCGSize:contentBounds]);

// set the height for the form view
[v.heightAnchor constraintEqualToConstant:contentBounds.height].active = YES;

// add it to the view, so we can confirm the height calculation
[self.view addSubview:v];

// center it on the view
[NSLayoutConstraint activateConstraints:
@[
[v.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[v.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor]
]
];

}

@end

//
// FormViewController.h
// Created by Don Mag on 4/8/19.
//

#import <UIKit/UIKit.h>

@interface FormViewController : UIViewController

@property (strong, nonatomic) UILabel *topLabel;
@property (strong, nonatomic) UITextField *theTextField;
@property (strong, nonatomic) UILabel *bottomLabel;

@end

//
// FormViewController.m
// Created by Don Mag on 4/8/19.
//

#import "FormViewController.h"

@interface FormViewController ()
@end

@implementation FormViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor redColor];

// create a multi-line "top label"
_topLabel = [UILabel new];
_topLabel.backgroundColor = [UIColor cyanColor];
_topLabel.text = @"Hello Top Label";
_topLabel.numberOfLines = 0;

// create a text field
_theTextField = [UITextField new];
_theTextField.backgroundColor = [UIColor greenColor]; // just to make it easy to see
_theTextField.borderStyle = UITextBorderStyleRoundedRect;
_theTextField.text = @"The Text Field";

// create a multi-line "bottom label"
_bottomLabel = [UILabel new];
_bottomLabel.backgroundColor = [UIColor cyanColor];
_bottomLabel.text = @"Hello Bottom Label";
_bottomLabel.numberOfLines = 0;

// we're using auto-layout and constraints
_topLabel.translatesAutoresizingMaskIntoConstraints = NO;
_theTextField.translatesAutoresizingMaskIntoConstraints = NO;
_bottomLabel.translatesAutoresizingMaskIntoConstraints = NO;

// add to view
[self.view addSubview:_topLabel];
[self.view addSubview:_theTextField];
[self.view addSubview:_bottomLabel];

// these elements and constraints will define the height of the content
[NSLayoutConstraint activateConstraints:
@[

// constrain top label leading, trailing and top to top of view, all at 20-pts
[_topLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:20.0],
[_topLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20.0],
[_topLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20.0],

// constrain text field leading and trailing, and top to bottom of top label, all at 20-pts
[_theTextField.topAnchor constraintEqualToAnchor:_topLabel.bottomAnchor constant:20.0],
[_theTextField.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20.0],
[_theTextField.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20.0],

// constrain bottom label leading, trailing and top to bottom of text field, all at 20-pts
[_bottomLabel.topAnchor constraintEqualToAnchor:_theTextField.bottomAnchor constant:20.0],
[_bottomLabel.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-20.0],
[_bottomLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20.0],

// AND constrain bottom label to bottom of view at 20-pts
[_bottomLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20.0]

]
];

}

@end

结果(将加载的 VC 的 View 添加为 subview - 参见代码中的注释):

enter image description here

并用更多文字显示自动高度计算:

enter image description here

如果您更改标签的文本量(在 ViewController.m 中设置),您将看到高度计算正确。

关于ios - 在将 View 添加到 View 树之前如何计算 UIViewController 高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55574511/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com