使用自动布局的 XIB 中的 UIView 始终为 600x600

UIView in XIB using Autolayout is always 600x600

我创建了一个单独的 .xib,因为我想在 viewController 之外设计一个带有 autolayoutUIView。我创建了 .xib,使用 wCompact hRegular 添加了 UIView 和约束。简单。

然后添加到我的viewControllerviewDidLoad:

UIView *header = [[[NSBundle mainBundle] loadNibNamed:@"HeaderSearch" owner:self options:nil] lastObject];
NSLog(@"%@", NSStringFromCGRect(header.frame));
[self.view addSubview:header];

但是,添加后,帧大小为 600x600,我不知道为什么。

我在这里做错了什么导致这个奇怪的尺寸?

请参考这个

header.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:header];

NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:header attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];
[self.view addConstraint:widthConstraint];

NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:header attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:130.0];
[self.view addConstraint:widthConstraint];
[self.view addConstraint:heightConstraint];

您需要取消选中 xib

中的 'Use size classes'

并且视图框架大小将是您设置的大小,而不是 600x600

如果是Xcode8禁用"Use Trait Variations"

我遇到了类似的问题,但就我而言,我不想关闭特征变化或大小 类。我还从 XIB 加载了一些视图,但我使用了这个方便的助手类别:

@implementation UIView (Initialization)

+ (instancetype)instantiateFromNib {
    return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:nil options:nil] firstObject];
}

@end

我不想引入用代码编写的约束,因此向我的视图控制器添加了一个覆盖的 viewWillLayoutSubviews 方法,如下所示:

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    [self.firstView setFrame:self.view.bounds];
    [self.secondView setFrame:self.view.bounds];
}

在我的例子中,firstViewsecondView 只是整个视图控制器的覆盖。

我认为,这是最好的正确方法:

- (void)willMoveToParentViewController:(UIViewController *)parent {
    [super willMoveToParentViewController:parent];

    self.view.frame = parent.view.frame;
    [self.view layoutIfNeeded];

    // adjust subviews here
}

视图将获得正确的框架,并且调整只会在初始化时调用一次。