ios10:viewDidLoad框架宽度/高度未正确初始化 [英] ios10: viewDidLoad frame width/height not initialized correctly

查看:395
本文介绍了ios10:viewDidLoad框架宽度/高度未正确初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从升级到XCode8 GM和ios10以来,通过Interface Builder创建的所有视图都没有正确初始化,直到比预期晚得多的时候.这意味着在viewDidLoad,cellForRowAtIndexPath,viewWillAppear等中,每个视图的帧大小均设置为{1000,1000}.他们似乎在某些时候纠正了,但为时已晚.

Since upgrading to XCode8 GM and ios10, all of my views created via Interface Builder are not being initialized correctly until much much later than expected. This means in viewDidLoad, cellForRowAtIndexPath, viewWillAppear, etc, the frame size is set to {1000,1000} for every view. At some point they seem to correct, but its far too late.

遇到的第一个问题是常见的四角圆角全面失败:

The first problem encountered is with common rounding of corners failing across the board:

view.layer.cornerRadius = view.frame.size.width/2

对于依赖于帧大小的任何东西,在代码中进行计算都会显示出更多的问题.

Further problems are showing for anything that relies on frame size to do calculations in the code.

cellForRowAtIndexPath 

对于cellForRowAtIndexPath,帧大小在初始表显示时失败,但是一旦滚动它就可以正常工作. willDisplayCell:forRowAtIndexPath也不具有正确的帧大小.

For cellForRowAtIndexPath, frame size fails on initial table display, but then works fine once you scroll it. willDisplayCell:forRowAtIndexPath does not have the correct frame size either.

我已经硬编码了一些值,但是显然这是非常糟糕的代码实践,并且在我的项目中很多.

I've hardcoded a few values but obviously this is very bad code practice, as well as quite numerous in my projects.

有没有办法获得正确的镜框尺寸?

Is there a way or place to get correct frame sizes?

编辑

我发现使用高度/宽度约束而不是框架宽度height更为可靠.不过,这可能会增加需要很多新的IBOutlet来链接项目的高度/宽度约束的开销.

I've discovered that using the height/width constraint instead of frame width height is more reliable. This may add the overhead of needing lot of new IBOutlets to link the height/width constraints on items though.

现在,我已经创建了一个UIView类别,该类别使我可以直接访问View的高度/宽度约束,而无需使用IBOutlets.对于最小的使用,小循环应该没什么大不了的.没有创建宽度/高度限制的IB项目,结果不能保证.对于常数,最大可能返回0,或更糟糕的是返回0.另外,如果您没有高度/宽度约束,并且视图根据前/后约束来动态调整大小,则此方法将无效.

For now I've created a UIView category that lets me access a View's height/width constraints directly without the IBOutlets. For minimal use the small loop shouldn't be a big deal. Results not guaranteed for IB items without the width/height constraints created yet obviously. Probably returns 0 at best for the constant, or worse. Also, if you don't have a height/width constraint and your view is sized dynamically based on leading/trailing constraints, this won't work.

-viewDidLoad似乎具有正确的帧大小,但是如果您在此处进行修改,通常会导致UI的视觉变化.

-viewDidLoad appears to have correct frame size, but will often result in a visual change to the UI if you do modifications here.

UIView + WidthHeightConstraints.h

UIView+WidthHeightConstraints.h

@interface UIView (WidthHeightConstraints)

-(NSLayoutConstraint*)widthConstraint;
-(NSLayoutConstraint*)heightConstraint;
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute;

@end

UIView + WidthHeightConstraints.m

UIView+WidthHeightConstraints.m

#import "UIView+WidthHeightConstraints.h"

@implementation UIView (WidthHeightConstraints)

-(NSLayoutConstraint*)widthConstraint{
    return [self constraintForAttribute:NSLayoutAttributeWidth];
}
-(NSLayoutConstraint*)heightConstraint {
    return [self constraintForAttribute:NSLayoutAttributeHeight];
}
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute {
    NSLayoutConstraint *targetConstraint = nil;
    for (NSLayoutConstraint *constraint in self.constraints) {
        if (constraint.firstAttribute == attribute) {
            targetConstraint = constraint;
            break;
        }
    }
    return targetConstraint;
}

@end

编辑2

已证明上述类别仅部分有效.主要是因为ios似乎会自动添加几个额外的高度/宽度约束重复项,它们的类型为NSContentSizeLayoutConstraint,实际上与常规约束的大小不同. NSContentSizeLayoutConstraint也是一个私有类,因此我无法执行isKindOfClass来过滤掉它们.我还没有找到另一种有效测试这些方法的方法.这很烦人.

The category above has proven only partially effective. Mainly because ios appears to auto add a couple extra height/width constraint duplicates, that are of type NSContentSizeLayoutConstraint, which are actually not the same size as the normal constraint. The NSContentSizeLayoutConstraint is also a private class so I can't do isKindOfClass to filter those out. I haven't found another way to effectively test for those yet. This is annoying.

推荐答案

您描述的最常见问题仅出现在iOS 10中,可以通过添加以下行来解决(如有必要):

The most common issues you describe are appearing in iOS 10 only and can be solved by adding this line (if necessary):

self.view.layoutIfNeeded()

位于代码上方,负责更改约束,layer.cornerRadius等.

just above the code, that is responsible for changing constraint, layer.cornerRadius etc.

OR

将与框架/图层有关的代码放入viewDidLayoutSubviews()方法:

place your code related to frames / layers into viewDidLayoutSubviews() method:

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    view.layer.cornerRadius = self.myView.frame.size.width/2
    view.clipsToBounds = true

    ... etc
}

这篇关于ios10:viewDidLoad框架宽度/高度未正确初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆