宏定义
#pragma mark 判断是否是iPhoneX 系列
#define iPhoneX ((IS_IPHONE_X==YES || IS_IPHONE_Xr ==YES || IS_IPHONE_Xs== YES || IS_IPHONE_Xs_Max== YES) ? YES : NO)
//判断iPhoneX
#define IS_IPHONE_X ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
//判断iPHoneXr
#define IS_IPHONE_Xr ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) : NO)
//判断iPhoneXs
#define IS_IPHONE_Xs ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size): NO)
//判断iPhoneXs Max
#define IS_IPHONE_Xs_Max ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) : NO)
#define MSCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define MSCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
#define WX_VIEW_WIDTH_RATIO (CGFloat)MSCREEN_WIDTH/375.f
/// 高度iPhoneX适配
#define WX_VIEW_HEIGHT_RATIO (CGFloat)(iPhoneX ? WX_VIEW_WIDTH_RATIO : MSCREEN_HEIGHT/667.0)
不经意间发现了一个bug:
如果popViewControllerAnimated返回时,animated一个属性值的改变会导致iPhone X显示上的一个bug,但是它的根源暂未找到;
//正确的
[self.navigationController popViewControllerAnimated:YES];
//错误的
[self.navigationController popViewControllerAnimated:NO];
导致了tab和controller之间多了间隔-如图1所示:
Tabbar自定义与适配
tabbar上面是4个tab加一个自定义视图View 图3是点击中间按钮效果图
//CenterTabBar.h
@interface CenterTabBar : UITabBar
@property (nonatomic, strong) UIView *centerView;
@property (nonatomic, strong) UIView *topView;//
- (instancetype)initWithCenterView:(UIView *)centerView;
@end
//CenterTabBar.m
#import "CenterTabBar.h"
@interface CenterTabBar ()
{
UIEdgeInsets _oldSafeAreaInsets;
}
@end
@implementation CenterTabBar
- (instancetype)initWithCenterView:(UIView *)centerView
{
self = [super init];
if (self) {
self.centerView = centerView;
//防止tabbar的适应调整有问题
_oldSafeAreaInsets = UIEdgeInsetsZero;
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
_oldSafeAreaInsets = UIEdgeInsetsZero;
}
- (void)safeAreaInsetsDidChange {
[super safeAreaInsetsDidChange];
if (!UIEdgeInsetsEqualToEdgeInsets(_oldSafeAreaInsets, self.safeAreaInsets)) {
[self invalidateIntrinsicContentSize];
if (self.superview) {
[self.superview setNeedsLayout];
[self.superview layoutSubviews];
}
}
}
- (CGSize)sizeThatFits:(CGSize)size {
size = [super sizeThatFits:size];
if (@available(iOS 11.0, *)) {
float bottomInset = self.safeAreaInsets.bottom;
if (bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90)) {
size.height += bottomInset;
}
}
return size;
}
- (void)setFrame:(CGRect)frame {
if (self.superview) {
if (frame.origin.y + frame.size.height != self.superview.frame.size.height) {
frame.origin.y = self.superview.frame.size.height - frame.size.height;
}
}
[super setFrame:frame];
}
- (void)layoutSubviews
{
[super layoutSubviews];
// 把 tabBarButton 取出来(把 tabBar 的 subViews 打印出来就明白了)
CGFloat width = self.frame.size.width;
CGFloat tabbar_height = [UIScreen mainScreen].bounds.size.height >= 812.0f ? 83 - 22:49;
// 设置发布按钮的frame
NSInteger btnCount = 0;
if (self.centerView != nil) {
if (self.centerView.frame.size.height > tabbar_height) {
self.centerView.center = CGPointMake(width * 0.5, self.centerView.frame.size.height* 0.5);
CGRect frame = self.centerView.frame;
frame.origin.y = tabbar_height -self.centerView.frame.size.height;;
self.centerView.frame = frame;
btnCount = 5;
}else{
self.centerView.center = CGPointMake(width * 0.5, tabbar_height * 0.5);
btnCount = 5;
}
[self addSubview:self.centerView];
[self addSubview:self.topView];
self.topView.center = CGPointMake(width * 0.5, tabbar_height * 0.5-35*WX_VIEW_HEIGHT_RATIO);
self.topView.hidden = [[[NSUserDefaults standardUserDefaults] valueForKey:@"isFirstClickCreateBtn"] boolValue];
}else{
btnCount = 4;
}
// 设置其他的UITabBar的frame
CGFloat buttonY = 0;
CGFloat buttonW = width/btnCount;
CGFloat buttonH = tabbar_height;
NSInteger index = 0;
for (UIView * button in self.subviews) {
// 由于UITabBar是苹果官方私有的, 所以不能直接设置
if (![button isKindOfClass:NSClassFromString(@"UITabBarButton")]) continue;
// 计算按钮的x值
if (self.centerView) {
CGFloat buttonX = buttonW * ((index > 1) ? (index + 1): (index));
button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
}else{
CGFloat buttonX = buttonW * index;
button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
}
// 索引增加
index ++;
}
}
-(UIView *)topView
{
if (!_topView) {
_topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 105*WX_VIEW_WIDTH_RATIO, 38*WX_VIEW_HEIGHT_RATIO)];
UIImageView *bgImage = [[UIImageView alloc] initWithImage:MImageNamed(@"icon_add_topView")];
[_topView addSubview:bgImage];
[bgImage mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.topView);
}];
UILabel *lab = [UILabel new];
lab.text = @"点击发布内容";
lab.textColor = MWhiteColor;
lab.font = MSYSTEM_BOLD_FONT(12);
lab.textAlignment = NSTextAlignmentCenter;
[_topView addSubview:lab];
[lab mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.topView);
make.centerY.equalTo(self.topView).offset(-4);
}];
}
return _topView;
}
//重写hitTest方法,去监听中间按钮的点击,目的是为了让凸出的部分点击也有反应
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
//这一个判断是关键,不判断的话push到其他页面,点击中间按钮的位置也是会有反应的,这样就不好了
//self.isHidden == NO 说明当前页面是有TabBar的,那么肯定是在根控制器页面
//在根控制器页面,那么我们就需要判断手指点击的位置是否在中间按钮或“添加”标签上
//是的话让中间按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
if (self.isHidden == NO)
{
//将当前TabBar的触摸点转换坐标系,转换到中间按钮的身上,生成一个新的点
CGPoint newA = [self convertPoint:point toView:self.centerView];
//判断如果这个新的点是在中间按钮身上,那么处理点击事件最合适的view就是中间按钮
if ( [self.centerView pointInside:newA withEvent:event])
{
return self.centerView;
}
else
{//如果点不在中间按钮身上,直接让系统处理就可以了
return [super hitTest:point withEvent:event];
}
}
else
{
//TabBar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
return [super hitTest:point withEvent:event];
}
}
@end
//最后在UITabBarController.m里设置
//调整文字位置
if (iPhoneX) {
[[UITabBarItem appearance] setTitlePositionAdjustment:UIOffsetMake(0, -6)];
}else {
[[UITabBarItem appearance] setTitlePositionAdjustment:UIOffsetMake(0, -3)];
}