DSTabBarController

这是一个tabBarController(导航控制器)组件。简单易用,功能强大。轻量、低耦合以及良好的扩展性。通过简单的几行代码可以让你快速搭建起流行的应用UI架构。

普通的TabBar

如果你只想构建一个很普通的tabbarController,像这种:

1.gif

那么你只需要这样做

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [self rootViewController1];
    [self.window makeKeyAndVisible];
    return YES;
}
// 设置导航控制器TabBarController
// 传入一个 `控制器数组` 和 `选项卡属性数组`
- (UIViewController *)rootViewController1
{
    
    NSArray *viewControllers = [self viewControllers];
    NSArray *tabBarItems = [self tabBarItems];
    DSTabBarController *tabBarController = [DSTabBarController tabBarControllerWithViewControllers:viewControllers tabBarItems:tabBarItems];
    return tabBarController;
}

// 这个数组是 每个选项卡上对应的控制器
// 可以传字符串、Class或者控制器实例
- (NSArray *)viewControllers
{
     UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:[[DSFirstTableViewController alloc] initWithStyle:UITableViewStylePlain] ];
    return @[nav1,@"DSSecondViewController"];
}
//这是数组是 每个选项卡的属性
//数组中每个元素的类型是 `UITabBarItem`
- (NSArray *)tabBarItems
{
    UITabBarItem *tabBarItem1 = [[UITabBarItem alloc] initWithTitle:@"one" image:[UIImage imageNamed:@"my"] selectedImage:[UIImage imageNamed:@"my_h"]];
    UITabBarItem *tabBarItem2 = [[UITabBarItem alloc] initWithTitle:@"two" image:[UIImage imageNamed:@"home"] selectedImage:[UIImage imageNamed:@"home_h"]];
    return @[tabBarItem1,tabBarItem2];
}

DSTabBarController提供了一个遵守<DSTabBarControllerDelegate>的代理ds_delegate。他可以监听选项卡(实际上是UITabbarButton)的按下长按

- (UIViewController *)rootViewController1
{
    NSArray *viewControllers = [self viewControllers];
    NSArray *tabBarItems = [self tabBarItems];
    DSTabBarController *tabBarController = [DSTabBarController tabBarControllerWithViewControllers:viewControllers tabBarItems:tabBarItems];
    //设置代理
    tabBarController.ds_delegate = self;
    return tabBarController;
}

实现代理方法

- (void)tabBarController:(DSTabBarController *)tabBarController didClickTabBarButton:(UIControl *)tabBarButton viewController:(UIViewController *)viewController
{
    [self addZoonAnimationWithView:tabBarButton];
}

- (void)addZoonAnimationWithView:(UIView *)view
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"transform.scale";
    animation.values = @[@1.0,@1.3,@0.9,@1.15,@0.95,@1.02,@1.0];
    animation.duration = 0.9;
    animation.calculationMode = kCAAnimationCubic;
    [view.layer addAnimation:animation forKey:nil];
}

上面代码是当选项卡点击后,给选项卡添加了一个帧动画。效果如下:


2.gif

当需要监听选项卡长按时,需要实现下面的代理方法

//tabBarController默认是不能响应长按事件的
//如果需要支持长按 这里返回YES
- (BOOL)tabBarController:(DSTabBarController *)tabBarController shouldLongPressTabBarButton:(UIControl *)tabBarButton viewController:(UIViewController *)viewController
{
    return YES;
}
//这个方法里是写长按要实现的功能
- (void)tabBarController:(DSTabBarController *)tabBarController didLongPressUITabBarButton:(UIControl *)tabBarButton viewController:(UIViewController *)viewController
{
  //这里是长按功能的业务代码
    UIViewController *viewController = tabBarController.publishViewController;
    [UIView animateWithDuration:0.25 animations:^{
        viewController.view.layer.transform = CATransform3DMakeScale(0.95, 0.95, 0.7);
    }];
    UIAlertController *alerController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [UIView animateWithDuration:0.25 animations:^{
            viewController.view.layer.transform = CATransform3DIdentity;
        }];
     }];
    [alerController addAction:action];
    [viewController presentViewController:alerController animated:YES completion:nil];
}

设置后的效果如下:


3.gif

你还可以设置长按的时间

@property (nonatomic, assign) CFTimeInterval minimumPressDuration;// Default is 0.8. Time in seconds the fingers must be held down for the gesture to be recognized 

特殊的TabBar

像是闲鱼客户端的那种TabBar,TarBar的中间有个特殊的按钮,大致效果如下:


4.gif

这就需要数据源方法了,首先设置数据源

 tabBarController.ds_dataSource = self;

实现以下的数据源方法

//设置特殊按钮
- (UIButton *)tabBarControllerPublishButton:(DSTabBarController *)tabBarController
{
  return [self publishButton];
}

- (UIButton *)publishButton
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setImage:[UIImage imageNamed:@"yuanfenqi"] forState:UIControlStateNormal];[button setImage:[UIImage imageNamed:@"yuanfenqi_h"] forState:UIControlStateSelected];
    button.backgroundColor =[UIColor cyanColor];
    //默认`sizeToFit`
    button.frame = CGRectMake(0, 0, 100, 100);
    button.showsTouchWhenHighlighted = YES;
    return button;
}

监听特殊按钮的点击

- (void)tabBarController:(DSTabBarController *)tabBarController didClickPublishButton:(UIButton *)button
{
    //添加关键帧动画
    [self addZoonAnimationWithView:button];
    //执行按钮点击后的事件
    //这里写你的业务逻辑代码
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor =[UIColor yellowColor];
    vc.modalPresentationStyle = UIModalPresentationCustom;
    vc.view.alpha = 0.9;
    [tabBarController.selectedViewController presentViewController:vc animated:YES completion:nil];
}
关于特殊按钮的位置

若需要指定特殊按钮的位置,实现以下数据源方法

- (NSUInteger)tabBarControllerPublishButtonIndex:(DSTabBarController *)tabBarController
{
    return 1;
}

若没有指定特殊按钮的位置,有如下简单的规则:

如果TabBar上总选项卡个数是奇数个,则特殊按钮居中;
如果TabBar上总选项卡个数是偶数个,特殊按钮会在最后一个位置。

如果你的应用点击特殊按钮不是弹出一个单独的控制器,而是根TabBar上的其他选项卡一样,需要实现以下数据源方法

- (UIViewController *)tabBarControllerSelectPublishButtonViewController:(DSTabBarController *)tabBarController
{
    UIViewController *vc= [[UIViewController alloc] init];
    vc.title  = @"Text";
    vc.view.backgroundColor = [UIColor yellowColor];
    return [[UINavigationController alloc] initWithRootViewController:vc];
}

效果如下图:

5.gif

监听特殊按钮的长按

- (BOOL)tabBarController:(DSTabBarController *)tabBarController shouldLongPressPublishButton:(UIButton *)button
{
    return YES;
}

//这个方法里是写长按要实现的功能
- (void)tabBarController:(DSTabBarController *)tabBarController didLongPressPublishButton:(UIButton *)button
{
    UIViewController *viewController = tabBarController.publishViewController;
    [UIView animateWithDuration:0.25 animations:^{
        viewController.view.layer.transform = CATransform3DMakeScale(0.95, 0.95, 0.7);
    }];
    UIAlertController *alerController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleActionSheet];
    
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [UIView animateWithDuration:0.25 animations:^{
            viewController.view.layer.transform = CATransform3DIdentity;
        }];
        
    }];
    [alerController addAction:action];
    [viewController presentViewController:alerController animated:YES completion:nil];
}

PS:
最低支持:iOS7
支持Pod:Pod 'DSTabBarController'
Demo地址:DSTabBarController

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,613评论 4 59
  • Fab燕燕阅读 144评论 0 0
  • 近轻断食的概念又被翻出来,虽然但凡有一点营养常识的人肯定对这种概念嗤之以鼻,但是搭这个热点宣传自己也不乏是一种吸粉...
    健康起飞吧阅读 178评论 0 0
  • 毕业入职以来,使用 SVN 版本控制工具管理代码,记录以下对于工作中较好的使用 SVN 配置; 1. 配置忽略文件...
    dongbingliu阅读 393评论 0 1
  • 为了储备更多的体力,马拉松运动员一般会采用“淀粉饥饿法”。其基本的原理是利用赛前一周的时间来大量储存体内的糖原,等...
    青松跑步阅读 1,869评论 0 2