IOS自定义TabBar(OC和Swift)

OC Demo : 传送门
SwfitDemo : 传送门

效果图

滑动隐藏Tabbar.gif
自定义小红点.gif
凸起来的加号按钮tabbar.gif
淘宝按钮tabbar.gif
动画按钮tabbar.gif
京东起弹Tabbar.gif

思路一、(类似闲鱼点击跳转其他界面的)
1、使用KVC:如果要修系统的某些属性,但被设为readOnly,就是用KVC,即setValue:>forKey
2、创建比需要显示UITabBarController的控制器少一个的控制器的viewControllers
3、自定义一个tabBar、使用layoutSubviews或init(frame: CGRect)、定位到自己喜欢的位置
4、在自定义tabBar创建一个按钮、使用代理可以跳转其他的界面

OC代码
CustomTabBarViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface CustomTabBarViewController : UITabBarController

@end

NS_ASSUME_NONNULL_END

CustomTabBarViewController.m

#import "CustomTabBarViewController.h"
#import "Demo1ViewController.h"
#import "Demo2ViewController.h"
#import "Demo3ViewController.h"
#import "Demo4ViewController.h"
#import "Demo5ViewController.h"
#import "SimpleCustomDemoViewController.h"
#import "CustomTabBar.h"

@interface CustomTabBarViewController ()<UITabBarControllerDelegate, CustomTabBarDelegate>

@property (strong, nonatomic) CustomTabBar *customTabBar;

@end

@implementation CustomTabBarViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    CustomTabBar *tabBar = [[CustomTabBar alloc] init];
    //取消tabBar的透明效果
    tabBar.translucent = NO;
    // 设置tabBar的代理
    tabBar.myDelegate = self;
    // KVC:如果要修系统的某些属性,但被设为readOnly,就是用KVC,即setValue:forKey:。
    [self setValue:tabBar forKey:@"tabBar"];
    self.customTabBar = tabBar;
    
    [self tabBarControllerAddChildViewController];
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}

# pragma mark - 添加子类的数据
- (void)tabBarControllerAddChildViewController
{
    NSArray *classControllers = [NSArray array];
    classControllers = @[@"Demo1ViewController", @"Demo2ViewController", @"Demo4ViewController", @"Demo5ViewController"];
    NSArray *titles = @[@"首页", @"附近", @"聊天", @"我的"];
    NSArray *normalImages = @[@"home_normal", @"mycity_normal", @"message_normal", @"account_normal"];
    NSArray *selectImages = @[@"home_highlight", @"mycity_highlight", @"message_highlight", @"account_highlight"];
    
    [self TabbarControllerAddSubViewsControllers:classControllers addTitleArray:titles addNormalImagesArray:normalImages addSelectImageArray:selectImages];
}


# pragma mark - 初始化Tabbar里面的元素
- (void)TabbarControllerAddSubViewsControllers:(NSArray *)classControllersArray addTitleArray:(NSArray *)titleArray addNormalImagesArray:(NSArray *)normalImagesArray addSelectImageArray:(NSArray *)selectImageArray
{
    NSMutableArray *conArr = [NSMutableArray array];
    
    for (int i = 0; i < classControllersArray.count; i++) {
        
        Class cts = NSClassFromString(classControllersArray[I]);
        UIViewController *vc = [[cts alloc] init];
        UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:vc];
        [conArr addObject:naVC];
        
        UIImage *normalImage = [[UIImage imageNamed:normalImagesArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        UIImage *selectImage = [[UIImage imageNamed:selectImageArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
        vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:titleArray[i] image:normalImage selectedImage:selectImage];
        vc.tabBarItem.tag = I;

    }
    
    self.viewControllers = conArr;
    self.tabBar.tintColor = [UIColor colorWithRed:255.0/255 green:204.0/255 blue:13.0/255 alpha:1];
    self.tabBar.translucent = NO;
    
    self.delegate = self;
}

#pragma TaoBaoCustomTabBar
/**
 *  点击了加号按钮
 */
- (void)tabBarDidClickPlusButton:(CustomTabBar *)tabBar
{
    /**
     definesPresentationContext这一属性决定了那个父控制器的View,
     将会以优先于UIModalPresentationCurrentContext这种呈现方式来展现自己的View。
     如果没有父控制器设置这一属性,那么展示的控制器将会是根视图控制器
     
     modalPresentationStyle可以设置模态是否隐藏
     
     */
    
    tabBar.plusButton.selected = YES;
    
    SimpleCustomDemoViewController *vc = [SimpleCustomDemoViewController new];
    self.definesPresentationContext = YES;
    vc.view.backgroundColor = [UIColor clearColor];
    vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    [self presentViewController:vc animated:YES completion:nil];
}

# pragma mark - UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    self.customTabBar.plusButton.selected = NO;
    return YES;
}

@end

CustomTabBar.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@class CustomTabBar;

@protocol CustomTabBarDelegate <UITabBarDelegate>

@optional
// 当点击自定义tabbar的时候
- (void)tabBarDidClickPlusButton:(CustomTabBar *)tabBar;

@end


@interface CustomTabBar : UITabBar

@property (nonatomic, strong) UIButton *plusButton;

@property (nonatomic, weak) id<CustomTabBarDelegate> myDelegate;

@end

NS_ASSUME_NONNULL_END

CustomTabBar.m

#import "CustomTabBar.h"

@interface CustomTabBar ()

@end

@implementation CustomTabBar

# pragma mark - 赖加载
- (UIButton *)plusButton
{
    if (_plusButton == nil) {
        _plusButton = [[UIButton alloc] init];
        [_plusButton setImage:[UIImage imageNamed:@"post_normal"] forState:UIControlStateNormal];
        [_plusButton setImage:[UIImage imageNamed:@"post_normal"] forState:UIControlStateHighlighted];
       
        _plusButton.titleLabel.font = [UIFont systemFontOfSize:11];
        [_plusButton setTitle:@"发布" forState:UIControlStateNormal];
        [_plusButton setTitle:@"发布" forState:UIControlStateHighlighted];
        [_plusButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
//        [_plusButton setTitleColor:[UIColor colorWithRed:255.0/255 green:204.0/255 blue:13.0/255 alpha:1] forState:UIControlStateSelected];
       
        UIImage *buttonImg = [_plusButton imageForState:UIControlStateNormal];
        CGFloat titleWidth = [_plusButton.titleLabel.text sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont boldSystemFontOfSize:11],NSFontAttributeName, nil]].width;
        [_plusButton setTitleEdgeInsets:UIEdgeInsetsMake(buttonImg.size.height, -buttonImg.size.width, -15, 0)];
        [_plusButton setImageEdgeInsets:UIEdgeInsetsMake(-15, 0, 0, -titleWidth)];
        
        _plusButton.frame = CGRectMake(0, 0, _plusButton.imageView.image.size.width, _plusButton.imageView.image.size.height + 40);
        [_plusButton addTarget:self action:@selector(respondsToPlusButton) forControlEvents:UIControlEventTouchUpInside];
    }
    return _plusButton;
}

# pragma mark - CustomTabBarDelegate
- (void)respondsToPlusButton
{
    if ([self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
        [self.myDelegate tabBarDidClickPlusButton:self];
    }
}

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

# pragma mark - 重新布局
- (void)layoutSubviews
{
    [super layoutSubviews];
    // 设置中间按钮的位置
    self.plusButton.center = CGPointMake(CGRectGetWidth(self.frame) * 0.5, CGRectGetHeight(self.frame) * 0.1);
    
    // 设置其他的按钮的位置
    CGFloat w = CGRectGetWidth(self.frame) / 5;
    CGFloat index = 0;
    for (UIView *childView in self.subviews) {
        Class class = NSClassFromString(@"UITabBarButton");
        if ([childView isKindOfClass:class]) {
            childView.frame = CGRectMake(w * index, CGRectGetMinY(childView.frame), w, CGRectGetHeight(childView.frame));
            
            // 增加索引 要和中间的控件隔开
            index ++;
            if (index == 2) {
                index ++;
            }
            
        }
    }
}


# pragma mark - 重写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;
}


@end

Swift
CustomTabBarViewController.swift

import UIKit

class CustomTabBarViewController: UITabBarController, UITabBarControllerDelegate, CustomTabBarDelegate {
    
    var customTabBar1 = CustomTabBar()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let customTabBar = CustomTabBar()
        // 取消tabBar的透明效果
        customTabBar.isTranslucent = false
        // 设置tabBar的代理
        customTabBar.myDelegate = self
        self.customTabBar1 = customTabBar
        self.setValue(customTabBar, forKey: "tabBar")
        
        self.setUpTabBar()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    // MARK: - 控制器的信息
    func setUpTabBar() {
        
        let demo1VC  = Demo1ViewController()
        let demo2VC  = Demo2ViewController()
        let demo4VC  = Demo4ViewController()
        let demo5VC  = Demo5ViewController()
        
        creatTabbarView(viewController: demo1VC, image: "home_normal", selectImage: "home_highlight", title: "首页", tag: 1)
        creatTabbarView(viewController: demo2VC, image: "mycity_normal", selectImage: "mycity_highlight", title: "附近", tag: 2)
        creatTabbarView(viewController: demo4VC, image: "message_normal", selectImage: "message_highlight", title: "聊天", tag: 3)
        creatTabbarView(viewController: demo5VC, image: "account_normal", selectImage: "account_highlight", title: "我的", tag: 4)
        
        self.tabBar.tintColor = UIColor(red: 255/255.0, green: 204/255.0, blue: 13/255.0, alpha: 1)
        self.tabBar.isTranslucent = false
        
        self.viewControllers = [
            UINavigationController(rootViewController: demo1VC),
            UINavigationController(rootViewController: demo2VC),
            UINavigationController(rootViewController: demo4VC),
            UINavigationController(rootViewController: demo5VC),
        ];
        
        self.delegate = self
    }
    
    // MARK: - TabBar里面的文字图片
    func creatTabbarView(viewController:UIViewController, image:NSString, selectImage:NSString, title:NSString, tag:NSInteger) {
        // alwaysOriginal 始终绘制图片原始状态,不使用Tint Color。
        viewController.tabBarItem.image = UIImage(named: image as String)?.withRenderingMode(.alwaysOriginal)
        viewController.tabBarItem.selectedImage = UIImage(named: selectImage as String)?.withRenderingMode(.alwaysOriginal)
        viewController.title = title as String
        viewController.tabBarItem.tag = tag
    }
    
    // MARK: - UITabBarControllerDelegate
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        self.customTabBar1.plusButton.isSelected = false

        return true
    }
    
    // MARK: -- CustomTabBarDelegate
    func tabBarDidClickPlusButton() {
        /**
         definesPresentationContext这一属性决定了那个父控制器的View,
         将会以优先于UIModalPresentationCurrentContext这种呈现方式来展现自己的View。
         如果没有父控制器设置这一属性,那么展示的控制器将会是根视图控制器

         modalPresentationStyle可以设置模态是否隐藏

         */
        self.customTabBar1.plusButton.isSelected = true
        
        let vc = SimpleCustomDemoViewController()
        self.definesPresentationContext = true
        vc.view.backgroundColor = UIColor.clear
        vc.modalPresentationStyle = .custom
        self.present(vc, animated: true, completion: nil)
    }
    
}

CustomTabBar.swift

import UIKit

// 声明一个协议clcikDelegate,需要继承NSObjectProtocol
protocol CustomTabBarDelegate: NSObjectProtocol {
    func tabBarDidClickPlusButton()
}

class CustomTabBar: UITabBar {
    // 声明代理
    weak var myDelegate: CustomTabBarDelegate?
    
    // 懒加载中间的按钮
    lazy var plusButton: UIButton = {
        let plusButton = UIButton()
        plusButton.setImage(UIImage.init(named: "post_normal"), for: .normal)
        plusButton.setImage(UIImage.init(named: "post_normal"), for: .highlighted)
        plusButton.titleLabel?.font = UIFont.systemFont(ofSize: 11)
        plusButton.setTitle("发布", for: .normal)
        plusButton.setTitleColor(UIColor.gray, for: .normal)
//        plusButton.setTitleColor(UIColor.init(red: 255.0/255, green: 204.0/255, blue: 13.0/255, alpha: 1), for: .selected)
        
        let buttonImg: UIImage? = plusButton.image(for: .normal)
        // 暂时没有找到计算字符串长度的方法
//        var titleWidth: CGFloat? = NSString(string: plusButton.titleLabel?.text).size(attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: 18)]).width
        let titleWidth = self
        plusButton.titleEdgeInsets = UIEdgeInsets.init(top: buttonImg!.size.height, left: -buttonImg!.size.height, bottom: -15, right: 0)
        plusButton.imageEdgeInsets = UIEdgeInsets.init(top: -15, left: 0, bottom: 0, right: -20)

        
        plusButton.frame = CGRect.init(x: 0, y: 0, width: plusButton.imageView!.image!.size.width, height: plusButton.imageView!.image!.size.height + 40)
        plusButton.addTarget(self, action: #selector(CustomTabBar.respondsToPlusButton), for: .touchUpInside)
        return plusButton
    }()

    // MARK: - CustomTabBarDelegate
    @objc func respondsToPlusButton(){
        //和oc不一样的是,Swift中如果简单的调用代理方法, 不用判断代理能否响应
        if myDelegate != nil{
            myDelegate?.tabBarDidClickPlusButton()
        }
    }
 
    // MARK: - 重写父类方法必须写
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 添加按钮
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(self.plusButton)
    }
    
    // MARK: - 重新布局
    override func layoutSubviews() {
        super.layoutSubviews()
        // 设置中间的按钮的位置
        let x = self.frame.width * 0.5
        let y = self.frame.height * 0.1
        self.plusButton.center = CGPoint.init(x: x, y: y)
        
        let w = self.frame.width / 5
        var index = 0
        for childView:UIView in self.subviews {
            if childView.isKind(of: NSClassFromString("UITabBarButton")!){
                
                var isIphoneX:Bool = false
                let zeroNum:CGFloat = 0
                // 判断是否是刘海屏
                if #available(iOS 11.0, *) {
                    isIphoneX = UIApplication.shared.keyWindow!.safeAreaInsets.bottom > zeroNum
                }
                
                if isIphoneX {
                    childView.frame = CGRect.init(x: w * CGFloat(index), y: 0, width: w, height: self.frame.size.height - 34)
                }else{
                    childView.frame = CGRect.init(x: w * CGFloat(index), y: 0, width: w, height: self.frame.size.height )
                }
                

                index+=1
                if index == 2{
                    index+=1
                }

            }
        }
    }
    
    // MARK: - 重写hitTest方法,监听按钮的点击 让凸出tabbar的部分响应点击
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        
        /// 判断是否为根控制器
        if self.isHidden {
            /// tabbar隐藏 不在主页 系统处理
            return super.hitTest(point, with: event)
            
        }else{
            /// 将单钱触摸点转换到按钮上生成新的点
            let onButton = self.convert(point, to: self.plusButton)
            /// 判断新的点是否在按钮上
            if self.plusButton.point(inside: onButton, with: event){
                return plusButton
            }else{
                /// 不在按钮上 系统处理
                return super.hitTest(point, with: event)
            }
        }
    }
    
}

思路二、(类似淘宝的不用跳转其他的界面)
1、使用KVC:如果要修系统的某些属性,但被设为readOnly,就是用KVC,即setValue:>forKey
2、创建需要显示UITabBarController的控制器的viewControllers
3、自定义一个tabBar、使用layoutSubviews或init(frame: CGRect)、定位到自己喜欢的位置、覆盖需要自定义的tabBar
4、利用UITabBarControllerDelegate、控制自定义tabBar显示隐藏

OC
TaoBaoCustomTabBarViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface TaoBaoCustomTabBarViewController : UITabBarController

@end

NS_ASSUME_NONNULL_END

TaoBaoCustomTabBarViewController.m

#import "TaoBaoCustomTabBarViewController.h"
#import "Demo1ViewController.h"
#import "Demo2ViewController.h"
#import "Demo3ViewController.h"
#import "Demo4ViewController.h"
#import "Demo5ViewController.h"
#import "SimpleCustomDemoViewController.h"
#import "TaoBaoCustomTabBar.h"

@interface TaoBaoCustomTabBarViewController ()<UITabBarControllerDelegate, TaoBaoCustomTabBarDelegate>

@property (strong, nonatomic) TaoBaoCustomTabBar *customTabBar;

@end

@implementation TaoBaoCustomTabBarViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    TaoBaoCustomTabBar *tabBar = [[TaoBaoCustomTabBar alloc] init];
    //取消tabBar的透明效果
    tabBar.translucent = NO;
    // 设置tabBar的代理
    tabBar.myDelegate = self;
    // KVC:如果要修系统的某些属性,但被设为readOnly,就是用KVC,即setValue:forKey:。
    [self setValue:tabBar forKey:@"tabBar"];
    self.customTabBar = tabBar;
    
    [self tabBarControllerAddChildViewController];
    
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}

# pragma mark - 添加子类的数据
- (void)tabBarControllerAddChildViewController
{
    NSArray *classControllers = [NSArray array];
    classControllers = @[@"Demo1ViewController", @"Demo2ViewController",@"Demo3ViewController" ,@"Demo4ViewController", @"Demo5ViewController"];
    NSArray *titles = @[@"", @"首页", @"附近", @"聊天", @"我的"];
    NSArray *normalImages = @[@"", @"home_normal", @"mycity_normal", @"message_normal", @"account_normal"];
    NSArray *selectImages = @[@"", @"home_highlight", @"mycity_highlight", @"message_highlight", @"account_highlight"];
    
    [self TabbarControllerAddSubViewsControllers:classControllers addTitleArray:titles addNormalImagesArray:normalImages addSelectImageArray:selectImages];
}


# pragma mark - 初始化Tabbar里面的元素
- (void)TabbarControllerAddSubViewsControllers:(NSArray *)classControllersArray addTitleArray:(NSArray *)titleArray addNormalImagesArray:(NSArray *)normalImagesArray addSelectImageArray:(NSArray *)selectImageArray
{
    NSMutableArray *conArr = [NSMutableArray array];
    
    for (int i = 0; i < classControllersArray.count; i++) {
        
        Class cts = NSClassFromString(classControllersArray[I]);
        UIViewController *vc = [[cts alloc] init];
        UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:vc];
        [conArr addObject:naVC];
        
        UIImage *normalImage = [[UIImage imageNamed:normalImagesArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        UIImage *selectImage = [[UIImage imageNamed:selectImageArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
        vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:titleArray[i] image:normalImage selectedImage:selectImage];
        vc.tabBarItem.tag = I;

    }
    
    self.viewControllers = conArr;
    self.tabBar.tintColor = [UIColor colorWithRed:255.0/255 green:204.0/255 blue:13.0/255 alpha:1];
    self.tabBar.translucent = NO;
    
    self.delegate = self;
}

#pragma TaoBaoCustomTabBarDelegate
/**
 *  点击了淘宝按钮
 */
- (void)tabBarDidClickPlusButton:(TaoBaoCustomTabBar *)tabBar
{
    self.selectedIndex =0;
    self.customTabBar.plusButton.hidden = YES;
}

# pragma mark - UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    if (viewController.tabBarItem.tag == 0) {
        self.customTabBar.plusButton.selected = NO;
        self.customTabBar.plusButton.hidden = NO;
        self.viewControllers[0].tabBarItem.image = [[UIImage imageNamed:@""] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        self.viewControllers[0].tabBarItem.title = @"";

        return YES;
    }else{
        self.customTabBar.plusButton.hidden = YES;
        self.viewControllers[0].tabBarItem.image = [[UIImage imageNamed:@"home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        self.viewControllers[0].tabBarItem.title = @"首页";
        return YES;
    }
}

@end

TaoBaoCustomTabBar.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@class TaoBaoCustomTabBar;

@protocol TaoBaoCustomTabBarDelegate <UITabBarDelegate>

@optional
// 当点击自定义tabbar的时候
- (void)tabBarDidClickPlusButton:(TaoBaoCustomTabBar *)tabBar;

@end


@interface TaoBaoCustomTabBar : UITabBar

@property (nonatomic, strong) UIButton *plusButton;

@property (nonatomic, weak) id<TaoBaoCustomTabBarDelegate> myDelegate;

@end

NS_ASSUME_NONNULL_END

TaoBaoCustomTabBar.m

#import "TaoBaoCustomTabBar.h"

@interface TaoBaoCustomTabBar ()

@end

@implementation TaoBaoCustomTabBar

# pragma mark - 赖加载
- (UIButton *)plusButton
{
    if (_plusButton == nil) {
        _plusButton = [[UIButton alloc] init];
        [_plusButton setImage:[UIImage imageNamed:@"taobao"] forState:UIControlStateNormal];
        [_plusButton setImage:[UIImage imageNamed:@"taobao"] forState:UIControlStateHighlighted];
        
        _plusButton.frame = CGRectMake(0, 0, _plusButton.imageView.image.size.width + 1, _plusButton.imageView.image.size.height + 1);
        [_plusButton addTarget:self action:@selector(respondsToPlusButton) forControlEvents:UIControlEventTouchUpInside];
    }
    return _plusButton;
}

# pragma mark - TaoBaoCustomTabBarDelegate
- (void)respondsToPlusButton
{
    if ([self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
        [self.myDelegate tabBarDidClickPlusButton:self];
    }
}

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

# pragma mark - 重新布局
- (void)layoutSubviews
{
    [super layoutSubviews];

    // 设置淘宝按钮的位置
    CGFloat w = CGRectGetWidth(self.frame) / 5;
    CGFloat index = 0;
    for (UIView *childView in self.subviews) {
        Class class = NSClassFromString(@"UITabBarButton");
        if ([childView isKindOfClass:class]) {
            if (index == 0) {
                UIView *thisView = [[UIView alloc] initWithFrame:CGRectMake(w * index, CGRectGetMinY(childView.frame), w, CGRectGetHeight(childView.frame))];
                self.plusButton.center = CGPointMake(CGRectGetWidth(thisView.frame) * 0.5, CGRectGetHeight(thisView.frame) * 0.5);
            }
        }
    }
}


# pragma mark - 重写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;
}


@end

Swift
TaoBaoCustomTabBarViewController.swift

import UIKit

class TaoBaoCustomTabBarViewController: UITabBarController, UITabBarControllerDelegate, TaoBaoCustomTabBarDelegate {
    
    var customTabBar1 = TaoBaoCustomTabBar()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let customTabBar = TaoBaoCustomTabBar()
        // 取消tabBar的透明效果
        customTabBar.isTranslucent = false
        // 设置tabBar的代理
        customTabBar.myDelegate = self
        self.customTabBar1 = customTabBar
        self.setValue(customTabBar, forKey: "tabBar")
        
        self.setUpTabBar()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    // MARK: - 控制器的信息
    func setUpTabBar() {
        
        let demo1VC  = Demo1ViewController()
        let demo2VC  = Demo2ViewController()
        let demo3VC  = Demo3ViewController()
        let demo4VC  = Demo4ViewController()
        let demo5VC  = Demo5ViewController()
        
        creatTabbarView(viewController: demo1VC, image: "", selectImage: "", title: "", tag: 0)
        creatTabbarView(viewController: demo2VC, image: "home_normal", selectImage: "home_highlight", title: "首页", tag: 1)
        creatTabbarView(viewController: demo3VC, image: "mycity_normal", selectImage: "mycity_highlight", title: "附近", tag: 2)
        creatTabbarView(viewController: demo4VC, image: "message_normal", selectImage: "message_highlight", title: "聊天", tag: 3)
        creatTabbarView(viewController: demo5VC, image: "account_normal", selectImage: "account_highlight", title: "我的", tag: 4)
        
        self.tabBar.tintColor = UIColor(red: 255/255.0, green: 204/255.0, blue: 13/255.0, alpha: 1)
        self.tabBar.isTranslucent = false
        
        self.viewControllers = [
            UINavigationController(rootViewController: demo1VC),
            UINavigationController(rootViewController: demo2VC),
            UINavigationController(rootViewController: demo3VC),
            UINavigationController(rootViewController: demo4VC),
            UINavigationController(rootViewController: demo5VC),
        ];
        
        self.delegate = self
    }
    
    // MARK: - TabBar里面的文字图片
    func creatTabbarView(viewController:UIViewController, image:NSString, selectImage:NSString, title:NSString, tag:NSInteger) {
        // alwaysOriginal 始终绘制图片原始状态,不使用Tint Color。
        viewController.tabBarItem.image = UIImage(named: image as String)?.withRenderingMode(.alwaysOriginal)
        viewController.tabBarItem.selectedImage = UIImage(named: selectImage as String)?.withRenderingMode(.alwaysOriginal)
        viewController.tabBarItem.title = title as String
        viewController.tabBarItem.tag = tag
    }
    
    // MARK: - UITabBarControllerDelegate
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        if viewController.tabBarItem.tag != 0{
            self.customTabBar1.plusButton.isSelected = false
            self.customTabBar1.plusButton.isHidden = true
            self.viewControllers?[0].tabBarItem.image = UIImage.init(named: "home_normal")?.withRenderingMode(.alwaysOriginal)
            self.viewControllers?[0].tabBarItem.title = "首页"
        }

        return true
    }
    
    // MARK: -- TaoBaoCustomTabBarDelegate
    func tabBarDidClickPlusButton(tabBar:TaoBaoCustomTabBar) {
        self.selectedIndex = 0;
        tabBar.plusButton.isSelected = false;
        tabBar.plusButton.isHidden = false;
        self.viewControllers?[0].tabBarItem.image = UIImage.init(named: "")?.withRenderingMode(.alwaysOriginal)
        self.viewControllers?[0].tabBarItem.title = ""
    }
    
}


TaoBaoCustomTabBar.swift

import UIKit

// 声明一个协议clcikDelegate,需要继承NSObjectProtocol
protocol TaoBaoCustomTabBarDelegate: NSObjectProtocol {
    func tabBarDidClickPlusButton(tabBar:TaoBaoCustomTabBar)
}

class TaoBaoCustomTabBar: UITabBar {
    // 声明代理
    weak var myDelegate: TaoBaoCustomTabBarDelegate?
    
    // 懒加载中间的按钮
    lazy var plusButton: UIButton = {
        let plusButton = UIButton()
        plusButton.setImage(UIImage.init(named: "taobao"), for: .normal)
        plusButton.setImage(UIImage.init(named: "taobao"), for: .highlighted)
        plusButton.titleLabel?.font = UIFont.systemFont(ofSize: 11)
        plusButton.setTitle("", for: .normal)

        plusButton.frame = CGRect.init(x: 0, y: 0, width: plusButton.imageView!.image!.size.width, height: plusButton.imageView!.image!.size.height + 40)
        plusButton.addTarget(self, action: #selector(TaoBaoCustomTabBar.respondsToPlusButton), for: .touchUpInside)
        return plusButton
    }()

    // MARK: - TaoBaoCustomTabBarDelegate
    @objc func respondsToPlusButton(){
        //和oc不一样的是,Swift中如果简单的调用代理方法, 不用判断代理能否响应
        if myDelegate != nil{
            myDelegate?.tabBarDidClickPlusButton(tabBar: self)
        }
    }
 
    // MARK: - 重写父类方法必须写
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 添加按钮
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(self.plusButton)
    }
    
    // MARK: - 重新布局
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 设置淘宝按钮的位置
        let w = self.frame.width / 5
        let index = 0
        for childView:UIView in self.subviews {
            if childView.isKind(of: NSClassFromString("UITabBarButton")!){

                if index == 0 {
                    var isIphoneX:Bool = false
                    let zeroNum:CGFloat = 0
                    // 判断是否是刘海屏
                    if #available(iOS 11.0, *) {
                        isIphoneX = UIApplication.shared.keyWindow!.safeAreaInsets.bottom > zeroNum
                    }
                    
                    if isIphoneX {
                        self.plusButton.frame = CGRect.init(x: w * CGFloat(index), y: 0, width: w, height: self.frame.size.height - 34)
                    }else{
                        self.plusButton.frame = CGRect.init(x: w * CGFloat(index), y: 0, width: w, height: self.frame.size.height )
                    }
                }

            }
        }
    }
    
    // MARK: - 重写hitTest方法,监听按钮的点击 让凸出tabbar的部分响应点击
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        
        /// 判断是否为根控制器
        if self.isHidden {
            /// tabbar隐藏 不在主页 系统处理
            return super.hitTest(point, with: event)
            
        }else{
            /// 将单钱触摸点转换到按钮上生成新的点
            let onButton = self.convert(point, to: self.plusButton)
            /// 判断新的点是否在按钮上
            if self.plusButton.point(inside: onButton, with: event){
                return plusButton
            }else{
                /// 不在按钮上 系统处理
                return super.hitTest(point, with: event)
            }
        }
    }
    
}

思路三(动画音效按钮tabbar)
tabbar点击的时候会调用didSelectItem方法
读取父控件对应的tabbar、对tabbar实现帧动画
点击对声音使用AudioToolbox框架

OC
AnimationTabBarViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface AnimationTabBarViewController : UITabBarController

@end

NS_ASSUME_NONNULL_END

AnimationTabBarViewController.m

#import "AnimationTabBarViewController.h"
#import "Demo1ViewController.h"
#import "Demo2ViewController.h"
#import "Demo3ViewController.h"
#import "Demo4ViewController.h"
#import "Demo5ViewController.h"
// 音效框架
#import <AudioToolbox/AudioToolbox.h>

@interface AnimationTabBarViewController ()<UITabBarControllerDelegate>

@end

@implementation AnimationTabBarViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self tabBarControllerAddChildViewController];
    
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}

# pragma mark - 添加子类的数据
- (void)tabBarControllerAddChildViewController
{
    NSArray *classControllers = [NSArray array];
    classControllers = @[@"Demo1ViewController", @"Demo2ViewController", @"Demo3ViewController", @"Demo4ViewController", @"Demo5ViewController"];
    NSArray *titles = @[@"首页", @"附近", @"发布", @"聊天", @"我的"];
    NSArray *normalImages = @[@"home_normal", @"mycity_normal", @"mycity_normal", @"message_normal", @"account_normal"];
    NSArray *selectImages = @[@"home_highlight", @"mycity_highlight", @"mycity_highlight", @"message_highlight", @"account_highlight"];
    
    [self TabbarControllerAddSubViewsControllers:classControllers addTitleArray:titles addNormalImagesArray:normalImages addSelectImageArray:selectImages];
}


# pragma mark - 初始化Tabbar里面的元素
- (void)TabbarControllerAddSubViewsControllers:(NSArray *)classControllersArray addTitleArray:(NSArray *)titleArray addNormalImagesArray:(NSArray *)normalImagesArray addSelectImageArray:(NSArray *)selectImageArray
{
    NSMutableArray *conArr = [NSMutableArray array];
    
    for (int i = 0; i < classControllersArray.count; i++) {
        
        Class cts = NSClassFromString(classControllersArray[I]);
        UIViewController *vc = [[cts alloc] init];
        UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:vc];
        [conArr addObject:naVC];
        
        UIImage *normalImage = [[UIImage imageNamed:normalImagesArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        UIImage *selectImage = [[UIImage imageNamed:selectImageArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:titleArray[i] image:normalImage selectedImage:selectImage];
        vc.tabBarItem.tag = I;
        
    }
    
    self.viewControllers = conArr;
    self.tabBar.tintColor = [UIColor colorWithRed:255.0/255 green:204.0/255 blue:13.0/255 alpha:1];
    self.tabBar.translucent = NO;
    self.delegate = self;
}

# pragma mark - UITabBarControllerDelegate
/**
 点击TabBar的时候调用
 */
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
    [self animationWithIndex:item.tag];
}

- (void)animationWithIndex:(NSInteger) index {
    // 得到当前tabbar的下标
    NSMutableArray * tabbarbuttonArray = [NSMutableArray array];
    for (UIView *tabBarButton in self.tabBar.subviews) {
        if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            [tabbarbuttonArray addObject:tabBarButton];
        }
    }
    /**
     对当前下标的tabbar使用帧动画
     可以根据UI的具体要求进行动画渲染
     */
    CABasicAnimation*pulse = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    pulse.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    pulse.duration = 0.2;
    pulse.repeatCount = 1;
    pulse.autoreverses = YES;
    pulse.fromValue = [NSNumber numberWithFloat:0.7];
    pulse.toValue = [NSNumber numberWithFloat:1.3];
    [[tabbarbuttonArray[index] layer] addAnimation:pulse forKey:nil];
    [self playSoundEffect:@"music" type:@"wav"];
}

# pragma mark - 播放音效的方法
- (void)playSoundEffect:(NSString *)name type:(NSString *)type{
    // 获取音效文件路径
    NSString *resoucePath = [[NSBundle mainBundle] pathForResource:name ofType:type];
    SystemSoundID soundID;
    // 地址转换和赋值
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:resoucePath], &soundID);
    // 开始播放音效
    AudioServicesPlaySystemSound(soundID);
}

@end

AnimationTabBarViewController.swift

import UIKit
// 音效框架
import AudioToolbox

class AnimationTabBarViewController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setUpTabBar()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    // MARK: - 控制器的信息
    func setUpTabBar() {
        
        let demo1VC  = Demo1ViewController()
        let demo2VC  = Demo2ViewController()
        let demo3VC  = Demo3ViewController()
        let demo4VC  = Demo4ViewController()
        let demo5VC  = Demo5ViewController()
        
        creatTabbarView(viewController: demo1VC, image: "home_normal", selectImage: "home_highlight", title: "首页", tag: 0)
        creatTabbarView(viewController: demo2VC, image: "mycity_normal", selectImage: "mycity_highlight", title: "附近", tag: 1)
        creatTabbarView(viewController: demo3VC, image: "mycity_normal", selectImage: "mycity_highlight", title: "发布", tag: 2)
        creatTabbarView(viewController: demo4VC, image: "message_normal", selectImage: "message_highlight", title: "聊天", tag: 3)
        creatTabbarView(viewController: demo5VC, image: "account_normal", selectImage: "account_highlight", title: "我的", tag: 4)
        
        self.viewControllers = [
            UINavigationController(rootViewController: demo1VC),
            UINavigationController(rootViewController: demo2VC),
            UINavigationController(rootViewController: demo3VC),
            UINavigationController(rootViewController: demo4VC),
            UINavigationController(rootViewController: demo5VC),
        ];
        
        self.tabBar.tintColor = UIColor(red: 255/255.0, green: 204/255.0, blue: 13/255.0, alpha: 1)
        self.tabBar.isTranslucent = false
        self.delegate = self
    }
    
    // MARK: - TabBar里面的文字图片
    func creatTabbarView(viewController:UIViewController, image:NSString, selectImage:NSString, title:NSString, tag:NSInteger) {
        // alwaysOriginal 始终绘制图片原始状态,不使用Tint Color。
        viewController.tabBarItem.image = UIImage(named: image as String)?.withRenderingMode(.alwaysOriginal)
        viewController.tabBarItem.selectedImage = UIImage(named: selectImage as String)?.withRenderingMode(.alwaysOriginal)
        viewController.title = title as String
        viewController.tabBarItem.tag = tag
    }
    
    // MARK: - UITabBarControllerDelegate
    /**
     点击TabBar的时候调用
     */
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        self.touchAnimation(index: item.tag)
    }
    
    func touchAnimation(index:NSInteger){
        // 得到当前tabbar的下标
        var tabbarbuttonArray:NSMutableArray!
        tabbarbuttonArray = NSMutableArray.init()
        for tabBarButton:UIView in self.tabBar.subviews {
            if tabBarButton.isKind(of: NSClassFromString("UITabBarButton")!){
                tabbarbuttonArray.add(tabBarButton)
            }
        }
        /**
         对当前下标的tabbar使用帧动画
         可以根据UI的具体要求进行动画渲染
         */
        let pulse = CABasicAnimation.init(keyPath: "transform.scale")
        pulse.timingFunction = CAMediaTimingFunction.init(name: .easeInEaseOut)
        pulse.duration = 0.2
        pulse.repeatCount = 1
        pulse.autoreverses = true
        pulse.fromValue = 0.7
        pulse.toValue = 1.3
        let thisView = tabbarbuttonArray[index] as! UIView
        thisView.layer.add(pulse, forKey: nil)
        
        self.playSoundEffect(name: "music", type: "wav")
    }
    
    // MARK: - 播放音效的方法
    func playSoundEffect(name:String, type:String) {
        //获取声音地址
        let resoucePath = Bundle.main.path(forResource: name, ofType: type)
        var soundID:SystemSoundID = 0
        //地址转换
        let baseURL = NSURL(fileURLWithPath: resoucePath!)
        //赋值
        AudioServicesCreateSystemSoundID(baseURL, &soundID)
        //播放声音
        AudioServicesPlaySystemSound(soundID)
        
    }
}

思路四(京东tabbar)
1、在app文件里设置window的背景色、根据需求设置
2、写一个父类、让子控制器继承他。这个父类控制tabbar的动画
3、设置KVO模式、监听判断tabbar是否需要动画

OC代码
AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    return YES;
}

JDAnimationTabBarViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface JDAnimationTabBarViewController : UITabBarController

@end

NS_ASSUME_NONNULL_END

JDAnimationTabBarViewController.m

#import "JDAnimationTabBarViewController.h"
#import "Demo7ViewController.h"
#import "Demo2ViewController.h"
#import "Demo3ViewController.h"
#import "Demo4ViewController.h"
#import "Demo5ViewController.h"

@interface JDAnimationTabBarViewController ()

@end

@implementation JDAnimationTabBarViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self tabBarControllerAddChildViewController];
    
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}

# pragma mark - 添加子类的数据
- (void)tabBarControllerAddChildViewController
{
    NSArray *classControllers = [NSArray array];
    classControllers = @[@"Demo7ViewController", @"Demo2ViewController", @"Demo3ViewController", @"Demo4ViewController", @"Demo5ViewController"];
    NSArray *titles = @[@"首页", @"附近", @"是的", @"聊天", @"我的"];
    NSArray *normalImages = @[@"home_normal", @"mycity_normal", @"mycity_normal", @"message_normal", @"account_normal"];
    NSArray *selectImages = @[@"home_highlight", @"mycity_highlight", @"mycity_highlight", @"message_highlight", @"account_highlight"];
    
    [self TabbarControllerAddSubViewsControllers:classControllers addTitleArray:titles addNormalImagesArray:normalImages addSelectImageArray:selectImages];
}


# pragma mark - 初始化Tabbar里面的元素
- (void)TabbarControllerAddSubViewsControllers:(NSArray *)classControllersArray addTitleArray:(NSArray *)titleArray addNormalImagesArray:(NSArray *)normalImagesArray addSelectImageArray:(NSArray *)selectImageArray
{
    NSMutableArray *conArr = [NSMutableArray array];
    
    for (int i = 0; i < classControllersArray.count; i++) {
        
        Class cts = NSClassFromString(classControllersArray[I]);
        UIViewController *vc = [[cts alloc] init];
        UINavigationController *naVC = [[UINavigationController alloc] initWithRootViewController:vc];
        [conArr addObject:naVC];
        
        UIImage *normalImage = [[UIImage imageNamed:normalImagesArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        UIImage *selectImage = [[UIImage imageNamed:selectImageArray[i]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
        vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:titleArray[i] image:normalImage selectedImage:selectImage];
        vc.tabBarItem.tag = I;
    }
    
    self.viewControllers = conArr;
    self.tabBar.tintColor = [UIColor colorWithRed:255.0/255 green:204.0/255 blue:13.0/255 alpha:1];
    self.tabBar.translucent = NO;
}

@end

父类控制器让tabbar的控制器继承他
SuperViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SuperViewController : UIViewController

@end

NS_ASSUME_NONNULL_END

SuperViewController.m

#import "SuperViewController.h"


@interface SuperViewController ()

@end

@implementation SuperViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    //如果KVO、观察者有改变
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(isAnimation:) name:@"isAnimation" object:nil];
}

// 得到监听值
- (void)isAnimation:(NSNotification *)notification{
    NSNumber *number = [notification object];
    int num = [number intValue];
    if (num == 0) {
        self.tabBarController.tabBar.frame = CGRectMake(self.tabBarController.tabBar.frame.origin.x, self.tabBarController.tabBar.frame.origin.y + self.tabBarController.tabBar.frame.size.height, self.tabBarController.tabBar.frame.size.width, self.tabBarController.tabBar.frame.size.height);
    }else{
        [UIView animateWithDuration:0.5 animations:^{
            self.tabBarController.tabBar.frame = CGRectMake(self.tabBarController.tabBar.frame.origin.x, self.tabBarController.tabBar.frame.origin.y - self.tabBarController.tabBar.frame.size.height, self.tabBarController.tabBar.frame.size.width, self.tabBarController.tabBar.frame.size.height);
        }];
    }
}
@end

跳转的界面
Demo6ViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface Demo6ViewController : UIViewController

@end

NS_ASSUME_NONNULL_END

Demo6ViewController.m

#import "Demo6ViewController.h"

@interface Demo6ViewController ()

@end

@implementation Demo6ViewController

//移除KVO、观察者
- (void)dealloc {
    [self removeObserver:self forKeyPath:@"isAnimation" context:nil];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor yellowColor];
    
    // 设置KVO、观察者
    [self addObserver:self forKeyPath:@"isAnimation" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    // 对KVO、观察者发送信息
    [[NSNotificationCenter defaultCenter] postNotificationName:@"isAnimation" object:@0];
}

- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    // 对KVO、观察者发送信息
    [[NSNotificationCenter defaultCenter] postNotificationName:@"isAnimation" object:@1];
}

@end

tabbar控制器
Demo7ViewController.h

#import <UIKit/UIKit.h>
#import "SuperViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface Demo7ViewController : SuperViewController

@end

NS_ASSUME_NONNULL_END

Demo7ViewController.m

#import "Demo7ViewController.h"
#import "Demo6ViewController.h"

@interface Demo7ViewController ()

@end

@implementation Demo7ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor redColor];
    
    UIButton *backBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    [backBtn setTitle:@"Back" forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(backBtn) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:backBtn];
    
    UIButton *pushBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 200, 200, 200)];
    [pushBtn setTitle:@"push" forState:UIControlStateNormal];
    [pushBtn addTarget:self action:@selector(pushBtn) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:pushBtn];
}

# pragma mark - 返回按钮
- (void)backBtn
{
    [self.tabBarController dismissViewControllerAnimated:YES completion:nil];
}

# pragma mark - push
- (void)pushBtn
{
    Demo6ViewController *vc = [[Demo6ViewController alloc] init];
    vc.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:vc animated:YES];
}

@end

Swfit代码
app

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.window?.backgroundColor = UIColor.white
        return true
    }

JDAnimationTabBarViewController

import UIKit

class JDAnimationTabBarViewController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setUpTabBar()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    // MARK: - 控制器的信息
    func setUpTabBar() {
        
        let demo1VC  = Demo7ViewController()
        let demo2VC  = Demo2ViewController()
        let demo3VC  = Demo3ViewController()
        let demo4VC  = Demo4ViewController()
        let demo5VC  = Demo5ViewController()
        
        creatTabbarView(viewController: demo1VC, image: "home_normal", selectImage: "home_highlight", title: "首页", tag: 1)
        creatTabbarView(viewController: demo2VC, image: "mycity_normal", selectImage: "mycity_highlight", title: "附近", tag: 2)
        creatTabbarView(viewController: demo3VC, image: "mycity_normal", selectImage: "mycity_highlight", title: "你好", tag: 3)
        creatTabbarView(viewController: demo4VC, image: "message_normal", selectImage: "message_highlight", title: "聊天", tag: 4)
        creatTabbarView(viewController: demo5VC, image: "account_normal", selectImage: "account_highlight", title: "我的", tag: 5)
        
        self.tabBar.tintColor = UIColor(red: 255/255.0, green: 204/255.0, blue: 13/255.0, alpha: 1)
        self.tabBar.isTranslucent = false
        
        self.viewControllers = [
            UINavigationController(rootViewController: demo1VC),
            UINavigationController(rootViewController: demo2VC),
            UINavigationController(rootViewController: demo3VC),
            UINavigationController(rootViewController: demo4VC),
            UINavigationController(rootViewController: demo5VC),
        ];
        
    }
    
    // MARK: - TabBar里面的文字图片
    func creatTabbarView(viewController:UIViewController, image:NSString, selectImage:NSString, title:NSString, tag:NSInteger) {
        // alwaysOriginal 始终绘制图片原始状态,不使用Tint Color。
        viewController.tabBarItem.image = UIImage(named: image as String)?.withRenderingMode(.alwaysOriginal)
        viewController.tabBarItem.selectedImage = UIImage(named: selectImage as String)?.withRenderingMode(.alwaysOriginal)
        viewController.title = title as String
        viewController.tabBarItem.tag = tag
        
    }
    

}

父类控制器
SuperViewController

import UIKit

class SuperViewController: UIViewController {
    
    var index:Int = 0
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        //如果KVO、观察者有改变
        NotificationCenter.default.addObserver(self, selector: #selector(isAnimation), name: NSNotification.Name.init(rawValue: "isAnimation"), object: nil)
        
        if self.index == 1 {
            self.tabBarController?.tabBar.frame = CGRect.init(x: self.tabBarController!.tabBar.frame.origin.x, y: self.tabBarController!.tabBar.frame.origin.y + self.tabBarController!.tabBar.frame.size.height, width: self.tabBarController!.tabBar.frame.size.width, height: self.tabBarController!.tabBar.frame.size.height)
        }
        
    }
    
    // 得到监听值
    @objc func isAnimation(notification: Notification) {
        let number: NSNumber = notification.object as! NSNumber
        let num: Int = number.intValue
        
        if num == 0{
            self.index = 1
        }else{
            self.index = 0
            UIView.animate(withDuration: 0.5) {
                self.tabBarController?.tabBar.frame = CGRect.init(x: self.tabBarController!.tabBar.frame.origin.x, y: self.tabBarController!.tabBar.frame.origin.y - self.tabBarController!.tabBar.frame.size.height, width: self.tabBarController!.tabBar.frame.size.width, height: self.tabBarController!.tabBar.frame.size.height)
            }
        }
    }
}

跳转控制器
Demo6ViewController

import UIKit

class Demo6ViewController: UIViewController {
    
    // MARK: - 类似OC dealloc
    deinit {
        self.removeObserver(self, forKeyPath: "isAnimation", context: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.yellow
        // 设置KVO、观察者
        self.addObserver(self, forKeyPath: "isAnimation", options: .new, context: nil)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let number:NSNumber = 0

        // 对KVO、观察者发送信息
//        NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "isAnimation"), object: number)
        NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "isAnimation"), object: number)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        let number:NSNumber = 1
        // 对KVO、观察者发送信息
        NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "isAnimation"), object: number)
    }
}

tabbar控制器
Demo7ViewController

import UIKit

class Demo7ViewController: SuperViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.red
        
        let backBtn = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
        backBtn.setTitle("back", for: .normal)
        // 这里的#selector 不要重名
        backBtn.addTarget(self, action: #selector(backBtnCkick), for: .touchUpInside)
        self.view.addSubview(backBtn)
        
        let pushBtn = UIButton(frame: CGRect(x: 100, y: 200, width: 100, height: 100))
        pushBtn.setTitle("push", for: .normal)
        // 这里的#selector 不要重名
        pushBtn.addTarget(self, action: #selector(pushBtnCkick), for: .touchUpInside)
        self.view.addSubview(pushBtn)
    }
    
    // MARK: - 返回按钮
    @objc func backBtnCkick(){
        self.tabBarController?.dismiss(animated: true, completion: nil)
    }
    
    // MARK: - push按钮
    @objc func pushBtnCkick(){
        let demo6VC = Demo6ViewController()
        demo6VC.hidesBottomBarWhenPushed = true
        self.navigationController?.pushViewController(demo6VC, animated: true)
    }


}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 简介 UITabBar是iOS App中经常使用的系统控件,比如知名App:新浪微博,微信,腾讯QQ等。在实际的项...
    清蘂翅膀的技术阅读 1,857评论 0 6
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,092评论 1 32
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,238评论 0 13
  • �楔子Runtime是什么?见名知意,其概念无非就是“因为 Objective-C 是一门动态语言,所以它需要一个...
    abb266389fd0阅读 11,375评论 37 310
  • 周末是难得休息的日子 有点时间可以自由安排 我选择休息 健身 倘若有时间再去阅读一下 身体需要锻炼 这个是重中之重...
    三三不惑阅读 223评论 0 5