更新xcode8后点击xib文件 修改一个约束,xcode8需要选择Device 如下图:
xcode8需要选择Device
再运行却发现cell上的imageView消失了
第一时间在各个网站上搜素,却没有结果。xcode8刚出来碰到这个问题的人还不错吧,没有类似问题。
定位问题:
1.打断点看imageView
是否已经创建,打印imageView.image
与其frame
。排除问题
2.看是否是imageView.image
是否被正确赋值,我们工程使用SDWebImge
,要确定是否是第三方控件的原因。我就用直接赋值方法imageView.image = [UIImage imageNamed:@"xxxx"];
发现还是空白,就排除SDWebImge
的原因。
3.新建xib,创建相同视图,一步步测试查看。找到问题所在 在设置圆角后imageView
消失,去掉设置圆角代码后视图出现。
解决问题:
在搜素xcode 8 设置圆角时,在stackoverflow上找到相同问题。详细参考stackoverflow问答
- (void)awakeFromNib {
[super awakeFromNib];
[self layoutIfNeeded];
_headImageView.layer.cornerRadius = _headImageView.frame.size.width/2;
_headImageView.layer.masksToBounds = YES;
// Initialization
//这里设置圆角
}
[self layoutIfNeeded];
因为在- (void)awakeFromNib
方法里,autolayout自动布局还没完成。使用这句代码刷新页面布局,然后设置圆角。
之前在使用xib时在- (void)viewDidLoad
获取view.frame不是正确的frame。原因在于在- (void)viewDidLoad
方法里autolayout自动布局尚未完成。正确方法如下:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_headImageView.layer.cornerRadius = _headImageView.frame.size.width/2;
_headImageView.layer.masksToBounds = YES;
[_headImageView sd_setImageWithURL:[NSURL URLWithString:_workingInfo.headUrl] placeholderImage:[UIImage imageNamed:@"HomePage_Avatar"]];
}
附加知识:
- (void)layoutSubviews
- (void)layoutIfNeeded
- (void)setNeedsLayout
layoutSubviews在以下情况下会被调用:
1、init初始化不会触发layoutSubviews
但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发
2、addSubview会触发layoutSubviews
3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化
4、滚动一个UIScrollView会触发layoutSubviews
5、旋转Screen会触发父UIView上的layoutSubviews事件
6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件
在苹果的官方文档中强调:
You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.
layoutSubviews, 当我们在某个类的内部调整子视图位置时,需要调用。
刷新子对象布局
-layoutSubviews方法:这个方法,默认没有做任何事情,需要子类进行重写。
-setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用。
-layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded];。