MG--快速创建tabBarController

  • 前言:

    • 开发中,搭建项目的基本框架,都会使用TabbarContrller外加嵌套导航控制器去搭建,为了能够快速搭建,节省开发时间,于是我会尽量偷懒,一些简单的代码能尽量能不写代码就尽量不写

TabBar控制器

  • 快速代建项目的基本框架
//  LYMMainTabBarVC.m
//  01 - MG的基本框架
//  Created by ming on 14/12/1.
//  Copyright © 2014年 ming. All rights reserved.
//  说明:
/**
 *   参考代码:具体类和图片换一下即可用
 */

#import "LYMMainTabBarVC.h"
#import "LYMNavigationVC.h"
#import "LYMEssenceViewController.h"
#import "LYMNewViewController.h"
#import "LYMFriendViewController.h"
#import "LYMMeViewController.h"
#import "LYMTabBar.h"

@interface LYMMainTabBarVC ()<LYMTabBarDelaegate>

@end

@implementation LYMMainTabBarVC

- (void)viewDidLoad {
    [super viewDidLoad];
  
    // 1.当系统的Tabbar满足不了需求的时候,用自己的TabBar代替系统的TabBar
    // [self setValue:[[LYMTabBar alloc] init] forKey:@"tabBar"];
    
    // 2.初始化所有的自控制器
    [self setUpAllChildController];
    
}

#pragma mark ========= initialize ===========
+ (void)initialize{
    [[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:@"tabbar-light"]];
    NSDictionary *dict = @{
                           NSForegroundColorAttributeName:[UIColor grayColor]
                           };
    [[UITabBarItem appearance] setTitleTextAttributes:dict forState:UIControlStateNormal];
}

#pragma mark ========= 初始化所有的子控制器 =========
/**
 *  初始化所有的子控制器
 */
- (void)setUpAllChildController{
    // 1.精华界面
    LYMEssenceViewController *essenceCV = [[LYMEssenceViewController alloc] init];
    [self setNavOneChildViewController:essenceCV title:@"精华" image:@"tabBar_essence_icon" selImage:@"tabBar_essence_click_icon"];
    
    // 2.新手大厅
    LYMNewViewController *newVC = [[LYMNewViewController alloc] init];
    newVC.view.backgroundColor = [UIColor redColor];
    [self setNavOneChildViewController:newVC title:@"新帖" image:@"tabBar_new_icon"
        selImage:@"tabBar_new_click_icon"];
   
    // 3.朋友
    LYMFriendViewController *friendVC = [[LYMFriendViewController alloc] init];
    [self setNavOneChildViewController:friendVC  title:@"关注" image:@"tabBar_friendTrends_icon" selImage:@"tabBar_friendTrends_click_icon"];
    
    // 4.我
    LYMMeViewController *meVC = [[LYMMeViewController alloc] init];
    meVC.view.backgroundColor = [UIColor purpleColor];
    [self setNavOneChildViewController:meVC title:@"我" image:@"tabBar_me_icon"
        selImage:@"tabBar_me_click_icon"];
}

/**
 *  初始化一个子控制器的方法
 */
- (void)setNavOneChildViewController:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selImage:(NSString *)selImage {
    vc.tabBarItem.title = title;
    vc.tabBarItem.image = [UIImage imageNamed:image];
    vc.tabBarItem.selectedImage = [UIImage imageNamed:selImage];
    
    [self addChildViewController:[[LYMNavigationVC alloc] initWithRootViewController:vc]];
}

@end

导航控制器

  • 主要是重写push方法和设置全局导航栏样式,以及设置全局滑动返回手势
//  BSNavigationController.m
//  MGNaV
//  Created by ming on 14/12/17.
//  Copyright © 2014年 ming. All rights reserved.

#import "BSNavigationController.h"

#define BSBarButtonItemFont [UIFont systemFontOfSize:15]

@interface BSNavigationController ()<UIGestureRecognizerDelegate>

@end

@implementation BSNavigationController
/** 
 *  为什么在这里设置???
 *  设置导航栏全局样式
 *  因为这个只需要设置一次,因为这个方法程序只会执行一次
 */
+ (void)load{
    /// 1.UINavigationBar
    UINavigationBar *navBarAppearence = [UINavigationBar appearance];
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    dict[NSFontAttributeName] = [UIFont systemFontOfSize:17];
    [navBarAppearence setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
    [navBarAppearence setTitleTextAttributes:dict];
    
    /// 2.UIBarButtonItem
    UIBarButtonItem *barItemAppearence = [UIBarButtonItem appearance];
    NSMutableDictionary *normalDict = [NSMutableDictionary dictionary];
    normalDict[NSForegroundColorAttributeName] = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
    normalDict[NSFontAttributeName] = BSBarButtonItemFont;
    [barItemAppearence setTitleTextAttributes:normalDict forState:UIControlStateNormal];
    
    NSMutableDictionary *highLDict = [NSMutableDictionary dictionary];
    highLDict[NSForegroundColorAttributeName] = BSGlobalBgColor;
    highLDict[NSFontAttributeName] = BSBarButtonItemFont;
    [barItemAppearence setTitleTextAttributes:highLDict forState:UIControlStateHighlighted];
}
/*
 <UIScreenEdgePanGestureRecognizer: 0x7fe260640220; view = <UILayoutContainerView 0x7fe26062bba0>;
 target= <(action=handleNavigationTransition:,
 target=<_UINavigationInteractiveTransition 0x7fe26063f1a0>)>>
 
 1.UIScreenEdgePanGestureRecognizer 加在导航控制器的view上
 
 2.target:_UINavigationInteractiveTransition(触发手势的对象)
 
 3.action: handleNavigationTransition:(这个方法系统内部调用,不需要自己实现)
 
 触发UIScreenEdgePanGestureRecognizer就会调用target的handleNavigationTransition:方法
 */
- (void)viewDidLoad {
    [super viewDidLoad];
    // UIScreenEdgePanGestureRecognizer
    // Do any additional setup after loading the view.
    // 只要触发这个Pan手势,就会调用self对象pan方法
    // 1.创建全屏手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
    
    // 控制手势什么时候触发
    pan.delegate = self;
    
    // 全屏滑动返回
    [self.view addGestureRecognizer:pan];
    
    // 2.禁止边缘手势
    self.interactivePopGestureRecognizer.enabled = NO;
    
    // 实现滑动返回功能
//    self.interactivePopGestureRecognizer.delegate = self;
    
    // bug:假死:程序一直运行,但是界面动不了.
    // 在根控制器的view,不需要滑动返回,
    
    // 全屏滑动返回
    // 研究下系统自带的返回手势
//    NSLog(@"%@",self.interactivePopGestureRecognizer.delegate);
}

#pragma mark - UIGestureRecognizerDelegate 
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    // 不是根控制器就实现滑动返回功能
    return self.childViewControllers.count != 1;
}

// 拦截控制器的push操作
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    // 判断是否为根控制器
    if (self.childViewControllers.count > 0) { // 非根控制器
        // 统一设置设置返回按钮
        UIBarButtonItem *backItem = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"navigationButtonReturn"] highImage:[UIImage imageNamed:@"navigationButtonReturnClick"] norColor:BSColor(66, 66, 66) selColor:BSColor(255, 0, 0) title:@"返回" target:self action:@selector(backClick)];
    
        viewController.navigationItem.leftBarButtonItem = backItem;
        
        // 2.隐藏底部TabBar导航条
        viewController.hidesBottomBarWhenPushed = YES;
    }
    [super pushViewController:viewController animated:animated];
}

// 出栈
- (void)backClick{
    [self popViewControllerAnimated:YES];
}

@end

附注:当系统的Tabbar满足不了需求,很多时候,Tabbar界面上都会有个发布(➕)按钮,这时候就需要自定义Tabbar,而此文就是为快速解决这个问题而生

######################### .h文件 #########################
//  BSTabBar.h
//  MGTabBar
//  Created by ming on 14/12/17.
//  Copyright © 2014年 ming. All rights reserved.

#import <UIKit/UIKit.h>

@interface BSTabBar : UITabBar

/** 保存点击plusButton按钮之后要执行的代码 */
@property (nonatomic,strong) void(^operationBlock)();

@end

######################### .m文件 #########################
//  BSTabBar.m
//  MGTabBar
//  Created by ming on 14/12/17.
//  Copyright © 2014年 ming. All rights reserved.

#import "BSTabBar.h"

@interface BSTabBar ()

/** 发布按钮 */
@property (nonatomic,strong) UIButton *plusButton;
/** 记录上一次点击过的按钮的Tag */
@property (nonatomic,assign) NSInteger previousClicktag;
/** 记录上一次点击过的按钮 */
@property (nonatomic,strong) UIControl *previousClickTaBarButton;

@end

@implementation BSTabBar
/// 苹果也是懒加载的
// 懒加载plusButton并初始化该按钮
- (UIButton *)plusButton{
    if (!_plusButton) {
        _plusButton = [[UIButton alloc] init];

        [_plusButton setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
        [_plusButton setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
        
        [_plusButton sizeToFit];
        
        [self addSubview:_plusButton];
        
        // 监听按钮的点击
        [_plusButton addTarget:self action:@selector(plusButtonClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _plusButton;
}

// 重新布局TabBar的子控件
- (void)layoutSubviews{
    [super layoutSubviews];

    CGFloat width = self.width/( self.items.count + 1);
    CGFloat height = self.height;
    CGFloat x = 0;
    CGFloat y = 0;
    NSInteger i = 0;
    for (UIControl *tabBarButton in self.subviews) {
        if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
                if (i==2) {
                    i++;
                }
                x = i*width;
                tabBarButton.frame = CGRectMake(x, y, width, height);
                i++;
            
            tabBarButton.tag = i;
            [tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchUpInside];
            
            /// 短时间内连续点击,类似于鼠标的双击事件
//             [tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchDownRepeat];
        }
    }
    
    // 计算plusButton的位置
    self.plusButton.center = CGPointMake(self.width*0.5, self.height*0.5);
}

#pragma mark - 操作
// 监听加号➕按钮的点击
- (void)plusButtonClick{
    if (self.operationBlock) {
        self.operationBlock();
    }
}

/**
  *  重复点击TabBar的按钮,你想做什么事(比如:刷新界面)
 */
- (void)tabBarButtonClick:(UIControl *)tabBarButton{
    if (self.previousClicktag == tabBarButton.tag) {
        // 告诉其他人(按钮被重复点击了)
        [[NSNotificationCenter defaultCenter] postNotificationName:BSTabBarButtonRepeatClickNotification object:nil];
    }
    self.previousClicktag = tabBarButton.tag;
}

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

推荐阅读更多精彩内容