经过一晚上的不断努力终于搞明白了ios 11 iPhone X 模拟器上出现TabBar移动和跳转的Bug的原因,都是safeAreaInsets引起的!!!下面是解决问题的代码:
A: 对应的OC代码:
#import "MyTabBar.h"
@interface MyTabBar()
@property (nonatomic,assign) UIEdgeInsets oldSafeAreaInsets;
@end
@implementation MyTabBar
// 解决iPhone X TabBar跳转问题
- (void) safeAreaInsetsDidChange
{
[super safeAreaInsetsDidChange];
if(self.oldSafeAreaInsets.left != self.safeAreaInsets.left ||
self.oldSafeAreaInsets.right != self.safeAreaInsets.right ||
self.oldSafeAreaInsets.top != self.safeAreaInsets.top ||
self.oldSafeAreaInsets.bottom != self.safeAreaInsets.bottom)
{
self.oldSafeAreaInsets = self.safeAreaInsets;
[self invalidateIntrinsicContentSize];
}
}
// 解决iPhone X TabBar移动的问题
- (CGSize) sizeThatFits:(CGSize) size
{
CGSize s = [super sizeThatFits:size];
if(@available(iOS 11.0, *))
{
CGFloat bottomInset = self.safeAreaInsets.bottom;
if( bottomInset > 0 && s.height < 50) {
s.height += bottomInset;
}
}
return s;
}
}
@end
B: 对应的Swift代码:
class SafeAreaFixTabBar: UITabBar {
var oldSafeAreaInsets = UIEdgeInsets.zero
@available(iOS 11.0, *)
override func safeAreaInsetsDidChange() {
super.safeAreaInsetsDidChange()
if oldSafeAreaInsets != safeAreaInsets {
oldSafeAreaInsets = safeAreaInsets
invalidateIntrinsicContentSize()
superview?.setNeedsLayout()
superview?.layoutSubviews()
}
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
var size = super.sizeThatFits(size)
if #available(iOS 11.0, *) {
let bottomInset = safeAreaInsets.bottom
if bottomInset > 0 && size.height < 50 {
size.height += bottomInset
}
}
return size
}
}
把上面的代码放在继承UITabBar的子类里面,然后在UITabBarControler的子类里面[self setValue:tabBar forKeyPath:@"tabBar"];即可。
附:老外的文章链接:https://stackoverflow.com/questions/46214740/ios-11-iphone-x-simulator-uitabbar-icons-and-titles-being-rendered-on-top-coveri