自定义带加号的tabBar

在项目过程中,经常遇到系统原生的UITabBar无法满足我们的需求,这时候就难免需要我们自己根据需求去自定义一个tabBar了。

源码地址

先看一下最后的效果图:

自定义带加号的tabBar_第1张图片

以下是实现代码:

DBHTabBar.h

#import 

@class DBHTabBar;

@protocol DBHTabBarDelegate 

@optional

- (void)tabBarDidClickPlusButton:(DBHTabBar *)tabBar;

@end

@interface DBHTabBar : UITabBar

@property (nonatomic, weak) id myDelegate;

@end

DBHTabBar.m

#import "DBHTabBar.h"

@interface DBHTabBar ()

@property (nonatomic, strong) UIButton *plusButton;

@end

@implementation DBHTabBar

#pragma mark - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.plusButton];
    }
    return self;
}

#pragma mark - Event Responds
/**
 * 点击了加号按钮
 */
- (void)respondsToPlusButton
{
    // 通知代理
    if ([self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
        [self.myDelegate tabBarDidClickPlusButton:self];
    }
}

#pragma mark - Private Methods
/**
 *  重新布局系统tabBarItem
 */
- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // 1.设置加号按钮的位置
    self.plusButton.center = CGPointMake(CGRectGetWidth(self.frame) * 0.5, CGRectGetHeight(self.frame) * 0.1);
    
    // 2.设置其他tabbarButton的frame
    CGFloat tabBarButtonWidth = CGRectGetWidth(self.frame) / 5;
    CGFloat tabBarButtonIndex = 0;
    for (UIView *childView in self.subviews) {
        Class class = NSClassFromString(@"UITabBarButton");
        if ([childView isKindOfClass:class]) {
            // 设置位置
            childView.frame = CGRectMake(tabBarButtonWidth * tabBarButtonIndex, CGRectGetMinY(childView.frame), tabBarButtonWidth, CGRectGetHeight(childView.frame));
            // 增加索引
            tabBarButtonIndex += (tabBarButtonIndex == 1 ? 2 : 1);
        }
    }
}
/**
 重写hitTest方法以响应点击超出tabBar的加号按钮
 */
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.clipsToBounds && !self.hidden && self.alpha > 0) {
        UIView *result = [super hitTest:point withEvent:event];
        if (result) {
            return result;
        }
        else {
            for (UIView *subview in self.subviews.reverseObjectEnumerator) {
                CGPoint subPoint = [subview convertPoint:point fromView:self];
                result = [subview hitTest:subPoint withEvent:event];
                if (result) {
                    return result;
                }
            }
        }
    }
    return nil;
}

#pragma mark - Getters And Setters
- (UIButton *)plusButton {
    if (!_plusButton) {
        _plusButton = [[UIButton alloc] init];
        [_plusButton setImage:[UIImage imageNamed:@"plusButton"] forState:UIControlStateNormal];
        [_plusButton setImage:[UIImage imageNamed:@"plusButton_selected"] forState:UIControlStateHighlighted];
        
        _plusButton.frame = CGRectMake(0, 0, _plusButton.imageView.image.size.width, _plusButton.imageView.image.size.height);
        [_plusButton addTarget:self action:@selector(respondsToPlusButton) forControlEvents:UIControlEventTouchUpInside];
    }
    return _plusButton;
}

@end

使用的2个步骤方法:

1、在UITabBarController中新建一个tabBar并替换掉原有的tabBar

DBHTabBar *tabBar = [[DBHTabBar alloc] init];
    //取消tabBar的透明效果
    tabBar.translucent = NO;
    // 设置tabBar的代理
    tabBar.myDelegate = self;
    // KVC:如果要修系统的某些属性,但被设为readOnly,就是用KVC,即setValue:forKey:。
    [self setValue:tabBar forKey:@"tabBar"];
2、实现刚才自定义的tabBar中写的协议

/**
 *  点击了加号按钮
 */
- (void)tabBarDidClickPlusButton:(DBHTabBar *)tabBar
{
    // 在这里写你点击加号按钮需要做的操作,我这里是弹出一个提示框
    UIAlertController *promptAlert = [UIAlertController alertControllerWithTitle:@"提示" message:@"点击了加号按钮" preferredStyle:UIAlertControllerStyleAlert];
    [promptAlert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:promptAlert animated:YES completion:nil];
}

友情提示:当加号按钮超出tabBar时,点击超出的那一部分按钮事件将不会响应。不过,只需要重写tabBar中hitTest方法即可解决哦,重写方式已经在代码中贴出来了哦。

到此,就结束了,第一次尝试写博客,写的不清楚之处还望谅解。

你可能感兴趣的:(iOS)