对应GitHubDemo地址

对于iOS系列设备来说.底部的tabbar由于去掉了Home键,底部有一个安全区作为用户的手势交互区(使用一些手势来完成Home键的操作).一些使用UIView去自定义UITabbar的如果想适配iPhoneX的话就需要写1.一个判断设备的宏.2.tabbar高度的宏.

我觉得上面的方法太复杂了(比如又来了个iPhoneXX,或者是iPadXX怎么弄,新增判断?这不符合我的风格).我所在的这个公司吧,怎么讲呢.设计都比较洒脱随性.有这种需要自定义tabbar的需求.


iOS tab 在左边 iphone tab键_控件


第一.除了iPhoneX之外的iPhone的tabbar的"样式"都是固定的,高度是确定的.但是X底下加了一个条.高度就需要拉高.适配iPhoneX的话应该是下面的样子.


iOS tab 在左边 iphone tab键_iOS_02

那么,我们怎么去做呢.

首先.我们要明白一个事情.系统tabbar可以自动适配iPhoneX.但是上面的控件并不满足我们现在的需求.那么,我们就不要使用tabbar上的’UITabBarItem’.自己放两种不同Style的Button就搞定了

如果是代码创建,我们可以重写下面的方法

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self setupUI];
    }
    return self;
}

如果是Xib(StoryBoard)之类的可视化创建,我们可以重写,别说是layoutsubview.

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setupUI];
    }
    return self;
}

然后使用公共的-(void)setupUI去做初始化创建.

由于我们是用自定义的UIButton装做的UITabbarItem.所以不能使用UITabbar的代理方法来判断点击的是哪个"tabbarItem".
那么我们可以写一个定义一个Type

typedef NS_ENUM(NSUInteger, CHTabbarButtonType) {
    CHTabbarButtonTypeLeft,
    CHTabbarButtonTypeMid,
    CHTabbarButtonTypeRight,
};

然后定义一个Block来回传点击方法.

typedef void(^TabbarButtonClickBlock)(CHTabbarButtonType type);

@interface CHTabbar : UITabBar

@property (nonatomic ,copy) TabbarButtonClickBlock tabbarButtonClickBlock;

@end

注意
就我们的需求来说是完成了.但是UITabbar上的按钮超过了UITabbar.点击外头的按钮是无法响应对应方法的.但是我们可以通过hittest来让系统到底让什么控件(UIView或者是UIView的子类)响应方法.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

如果想单次点击多点击失效.可以搞个属性记录一下上次点击的Type.如果Type == 点击Button的tag(tag = xxxtype).那么就不响应Block.
对应GitHubDemo地址里头有一个判断圆形视图的判断方法.大家可以去看看.