问题

更新Xcode8后打开xib都会提示是否更新xib版本

更新版本后,以前在 awakeFromNib 方法里获取某个 UIView 的fame可能会失效,比如说

1
2
3
4
5
6
- (void)awakeFromNib {
[super awakeFromNib];
CGFloat raduis = _headImg.frame.size.height/2;
_headImg.layer.cornerRadius = raduis;
_headImg.layer.masksToBounds = YES;
}

这段设置圆角的代码看上去没任何问题,但是运行后会发现 _headImg 不见了,找了半天之后打断点后发现 _headImg 的bounds竟然是(0, 0, 1000, 1000)

在SO上查了一下,如果不是Xcode8的bug的话,应该就是苹果修改了xib的layout cycle导致的问题

参考链接

http://stackoverflow.com/questions/39380128/ios-10-gm-with-xcode-8-gm-causes-views-to-disappear-due-to-roundedcorners-clip

http://stackoverflow.com/questions/39136637/clipstobounds-causes-uiimage-to-not-display-in-ios10-xcode-8

解决办法

如果是一小部分地方受影响的话,那么只需要简单的在获取某个 UIView 的frame前加入一句 [self layoutIfNeeded] 就可以了,但是工程里影响到的类比较多,改动起来比较麻烦话,可以通过hook awakeFromNib 的方法进行解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@implementation NSObject (adaptXocde8)
+(void)load
{
Method originalMethod = class_getInstanceMethod([NSObject class], @selector(awakeFromNib));
Method swapMethod = class_getInstanceMethod([NSObject class], @selector(awakeFromNibNew));
method_exchangeImplementations(originalMethod, swapMethod);

}

- (void)awakeFromNibNew
{
if([self respondsToSelector:@selector(layoutIfNeeded)])
{
[self performSelector:@selector(layoutIfNeeded) withObject:nil];
}
[self awakeFromNibNew];
}
@end