我为这个案子制作了一个特殊的测试应用程序(对不起,已经删除了)
我在Storyboard中添加了一个关于我的控制器视图的视图,在Interface Builder中设置了AutoLayout约束,并使其中一个(垂直空间)对于不同的大小类是不同的. Screenshot from IB
所以任何高度的值都是100,任何宽度都是0,常规高度是0,常规宽度.
它的效果很好,在iPhone垂直距离顶部是100,在iPad上它是0.
此外,我为此约束制作了IBOutlet,并希望在运行时将其更改为10
@property (weak,nonatomic) IBOutlet NSLayoutConstraint *topVerticalConstraint;
似乎我无法改变它,因为它没有任何效果
- (void)viewDidLoad { [super viewDidLoad]; self.topVerticalConstraint.constant = 10; // it doesn't work }
虽然它在我删除Interface Builder中常规高度,常规宽度的值时有效.
我想念大小班吗?
解决方法
问题是,在-viewWillLayoutSubviews和-viewDidLayoutSubviews之间发生布局事件之前,约束尚未完全定义,其中来自IB的所有参数都起作用.
我的经验法则是:
我的经验法则是:
>如果您使用框架手动定位视图,您可以在-viewDidLoad之前完成,
>如果您使用自动布局约束进行定位,请尽早进行调整-viewDidLayoutSubviews;
第二个陈述仅考虑对IB中的约束进行代码调整.您在-viewDidLoad中进行的调整将被布局期间在IB中设置的参数覆盖.如果使用代码添加约束,可以在-viewDidLoad中设置它们,因为没有任何内容可以覆盖它们.
我已经改变了你的代码并且它有效:
#import "ViewController.h" @interface ViewController () @property (weak,nonatomic) IBOutlet NSLayoutConstraint *topVerticalConstraint; @property (weak,nonatomic) IBOutlet UIView *square; @property (assign,nonatomic) BOOL firstLayout; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.firstLayout = YES; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; if (self.firstLayout) { self.topVerticalConstraint.constant = 10; self.firstLayout = NO; } } @end
请注意,在ViewController的生命周期中多次调用-viewDidLayoutSubviews,因此您必须确保在初始加载时仅进行一次调整.