似乎在 Xcode 8 中,在 viewDidLoad
上,所有 viewcontroller 子视图都具有相同的 1000x1000 大小.奇怪的事情,但是没关系,viewDidLoad
从来都不是正确调整视图大小的最佳位置.
It seems that with Xcode 8, on viewDidLoad
, all viewcontroller subviews have the same size of 1000x1000. Strange thing, but okay, viewDidLoad
has never been the better place to correctly size the views.
但是 viewDidLayoutSubviews
是!
在我当前的项目中,我尝试打印按钮的大小:
And on my current project, I try to print the size of a button:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSLog(@"%@", self.myButton);
}
日志显示 myButton 的大小为 (1000x1000)!然后如果我登录一个按钮点击,例如,日志显示正常大小.
The log shows a size of (1000x1000) for myButton! Then if I log on a button click, for example, the log shows a normal size.
我正在使用自动布局.
这是一个错误吗?
现在,Interface Builder 让用户可以动态改变 storyboard 中每个视图控制器的大小,以模拟特定设备的大小.
Now, Interface Builder lets the user change dynamically the size of every view controllers in storyboard, to simulate the size of a certain device.
在此功能之前,用户应手动设置每个视图控制器的大小.所以视图控制器保存了一定的大小,在initWithCoder
中用来设置初始帧.
Before this functionality, the user should set manually each view controller size. So the view controller was saved with a certain size, which was used in initWithCoder
to set the initial frame.
现在,initWithCoder
似乎没有使用 storyboard 中定义的大小,而是为 viewcontroller 视图定义了 1000x1000 px 大小.它的所有子视图.
Now, it seems that initWithCoder
do not use the size defined in storyboard, and define a 1000x1000 px size for the viewcontroller view & all its subviews.
这不是问题,因为视图应始终使用以下任一布局解决方案:
This is not a problem, because views should always use either of these layout solutions:
自动布局,所有约束都会正确布局您的视图
autolayout, and all the constraints will layout correctly your views
autoresizingMask,它将布局每个没有附加任何约束的视图(注意自动布局和边距约束现在在同一个视图中兼容o/!)
autoresizingMask, which will layout each view which doesn't have any constraint attached to (note autolayout and margin constraints are now compatible in the same view o/ !)
但这是与视图层相关的所有布局内容的问题,例如cornerRadius
,因为既不是autolayout也不是autoresizing遮罩 适用于图层属性.
But this is a problem for all layout stuff related to the view layer, like cornerRadius
, since neither autolayout nor autoresizing mask applies to layer properties.
要回答这个问题,常见的方法是如果你在控制器中使用viewDidLayoutSubviews
,如果你在视图中使用layoutSubview
.至此(不要忘记调用他们的 super
相关方法),您可以确定所有布局工作都已完成!
To answer this problem, the common way is to use viewDidLayoutSubviews
if you are in the controller, or layoutSubview
if you are in a view. At this point (don't forget to call their super
relative methods), you are pretty sure that all layout stuff has been done!
相当确定?嗯……不完全是,我说过,这就是我问这个问题的原因,在某些情况下,这种方法的视图仍然具有 1000x1000 的大小.我认为我自己的问题没有答案.提供有关它的最大信息:
Pretty sure? Hum... not totally, I've remarked, and that's why I asked this question, in some cases the view still has its 1000x1000 size on this method. I think there is no answer to my own question. To give the maximum information about it:
1- 仅在布置单元格时才会发生!在 UITableViewCell
&UICollectionViewCell
子类,layoutSubview
将不会在 子视图正确布局后被调用.
1- it happends only when laying out cells! In UITableViewCell
& UICollectionViewCell
subclasses, layoutSubview
won't be called after subviews would be correctly layed out.
2- 正如@EugenDimboiu 所说(如果对您有用,请点赞他的答案),在未布局的子视图上调用 [myView layoutIfNeeded]
将及时正确布局.
2- As @EugenDimboiu remarked (please upvote his answer if useful for you), calling [myView layoutIfNeeded]
on the not-layed out subview will layout it correctly just in time.
- (void)layoutSubviews {
[super layoutSubviews];
NSLog (self.myLabel); // 1000x1000 size
[self.myLabel layoutIfNeeded];
NSLog (self.myLabel); // normal size
}
3- 在我看来,这绝对是一个错误.我已将其提交给雷达(id 28562874).
3- To my opinion, this is definitely a bug. I've submitted it to radar (id 28562874).
PS:我不是英语母语,所以如果我的语法需要更正,请随时编辑我的帖子;)
PS: I'm not english native, so feel free to edit my post if my grammar should be corrected ;)
PS2:如果您有更好的解决方案,请不要再写另一个答案.我将移动已接受的答案.
PS2: If you have any better solution, feel free not write another answer. I'll move the accepted answer.
这篇关于自 Xcode 8 和 iOS10 以来,viewDidLayoutSubviews 上的视图大小不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!