你所不知道的UITabBarButton?

作者: DXSmile | 来源:发表于2016-02-19 19:23 被阅读6001次

项目源码请查看我的GitHub项目地址:

https://github.com/DXSmile/-Usage-of-UITabBarButton-.git

对于KVC可以更改私有属性的一些补充,

http://www.jianshu.com/p/40cae3b556ac
大家看完这篇之后,可以看看这个补充!!!

摘要:UITabBarButton的相关介绍,已经通过新浪微博实例验证tabBar中间按钮的创建

阐述:

只要有一定开发经验的iOS攻城狮,只要你做过应用程序APP的开发,不可避免的都会用到UITabBarController, UITabBarController又称标签控制器 ,同样是管理多控制器的,我们一般的做法都是将多个(一般是4-6个之间)UINavigationController作为UITabBarController的子控件,添加到UITabBarController的导航标签栏(也叫工具条)UITabBar上;

今天在这里,我要讲的,不是怎样创建一个UITabBarController,因为,这个比较简单,也是每个iOS攻城狮所需要必备的技能,那么问题来了,今天,我要说什么呢 ?

细心的朋友估计已经看出来了, 没错, 我要讲的是, 在创建UITabBarController的UITabBar标签栏的时候, 容易困扰也容易被大家忽视的UITabBarButton的问题.

1.什么是UITabBarButton?

&1.

我们都知道UITabBarController下方的工具条称为UITabBar ,如果UITabBarController有N个子控制器,那么UITabBar内部就会有N 个UITabBarButton作为子控件与之对应。

也就是说,UITabBarButton是UITabBarController中各个子控制器在工具条中对应的按钮的称呼,

同时我们可以注意到一个现象,那就是我们创建好UITabBarButton之后,各个UITabBarButton在UITabBar中的位置是均分的,UITabBar的高度为49。
如: 我这里有一个创建好的UITabBarController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    // 创建4个子控制器
    [self setupChildViewController];
}

#pragma mark - 创建TabBarController的4个子控制器
// 封装创建TabBarController的4个子控制器的方法
- (void)setupChildViewController {
    
    // 添加四个TabBarController的子控制器UINavigationController
    // 首页Home
    UINavigationController *navHome = [self navigationControllerWithStoryboardName:@"DXHome"];
    [self setupOneChildViewController:navHome image:[UIImage imageNamed:@"tabbar_home"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_home_selected"] title:@"首页"];
    
    // 消息message
    UINavigationController *navMessage = [self navigationControllerWithStoryboardName:@"DXMessage"];
    [self setupOneChildViewController:navMessage image:[UIImage imageNamed:@"tabbar_message_center"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_message_center_selected"] title:@"消息"];

    // 发现discover
    UINavigationController *navDiscover = [self navigationControllerWithStoryboardName:@"DXDiscover"];
    [self setupOneChildViewController:navDiscover image:[UIImage imageNamed:@"tabbar_discover"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_discover_selected"] title:@"发现"];

    // 我profile
    UINavigationController *navProfile = [self navigationControllerWithStoryboardName:@"DXProfile"];
    [self setupOneChildViewController:navProfile image:[UIImage imageNamed:@"tabbar_profile"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_profile_selected"] title:@"我"];
    
    // 添加到tabBar
    self.viewControllers = @[navHome, navMessage, navDiscover, navProfile];

}

#pragma mark - 创建一个子控制器的方法
// 封装创建一个子控制器的方法
- (void)setupOneChildViewController:(UIViewController *)vc image:(UIImage *)image selectedImage:(UIImage *)selectedImage title:(NSString *)title {
  
    vc.tabBarItem.image = image;
    vc.tabBarItem.selectedImage = selectedImage;
    vc.tabBarItem.badgeValue = @"10";
    vc.tabBarItem.title = title;
}

#pragma mark - 封装通过storyboard创建NavigationController的方法
// 封装通过storyboard创建NavigationController的方法
- (UINavigationController *)navigationControllerWithStoryboardName:(NSString *)name {
    // 1. 加载storyboard文件
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:name bundle:nil];
    // 2. 创建Storyboard中的初始化控制器
    return [storyboard instantiateInitialViewController];
}


运行出来之后,效果是这样的:


自定义tabBar

通过,输出结果,可以看出, 我们已经成功的更改了tabBar的权限,改为了,我们自定义的tabBar, 那么此时我们需要来验证一下,是否还可以拿到UITabBarButton;

同样调用之前的方法: 这里我们在另一个方法中来测试,

// 系统在即将开始为view准备控件的时候调用这个方法
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"%@", self.tabBar.subviews);
}

输出结果为:


自定义之后重新验证UITabBarButton

那么接下来,我们就可以开始写代码了:

//  DXTabBar.m
//  DXSWeibo
//  Created by xiongdexi on 16/2/19.
//  Copyright © 2016年 DXSmile. All rights reserved.
//

#import "DXTabBar.h"
@interface DXTabBar ()
// 定义中间按钮的属性
@property (nonatomic, weak) UIButton *plusButton;
@end

@implementation DXTabBar
#pragma mark - 懒加载设置中间按钮 保证只有一个
- (UIButton *)plusButton {
   if (_plusButton == nil) {
       // 1.根据自定义类型初始化一个button
       UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
       // 2.设置btn的各状态的图片属性
       [btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
       [btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted];
       [btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
       [btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
       // 3. 设置btn按钮的尺寸和图片的默认大小一样大
       [btn sizeToFit];
       
       // 4. 把按钮赋值给_plusButton
       _plusButton = btn;
       
       // 5. 把按钮添加到tabBar中 ,建立强引用
       [self addSubview:_plusButton];
   } 
   return _plusButton;
}

#pragma mark - 调整子控件的位置和尺寸
// 调整子控件的位置和尺寸
- (void)layoutSubviews {
   [super layoutSubviews];
   CGFloat w = self.bounds.size.width;
   CGFloat h = self.bounds.size.height;
   
   CGFloat butX = 0;  // x 是不确定的,可以初始化为0
   CGFloat butY = 0;  // y 就是0
   CGFloat butW = w / (self.items.count + 1); // 有几个UITabBarButton就有几个items模型
   CGFloat butH = h;
   
   int i = 0; // 定义角标,初始化为0
   // 调整系统自带的tabBar上面的按钮的位置
   for (UIView *tabBarButton in self.subviews) {
       // 判断是否是UITabBarButton
       if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
           
           // 因为中间需要预留一个位置,所以,当i到中间的是,就跳过
           if (i == 2) {
               i = 3;
           }
           butX = i * butW;  
           tabBarButton.frame = CGRectMake(butX, butY, butW, butH);
           i++;
       }
   }

   // 设置中间按钮的位置
   self.plusButton.center = CGPointMake(w * 0.5, h * 0.5);
}

效果图:

中间按钮效果图

相关文章

网友评论

  • 宋鸿康iOS:文章中的图片显示不出来了...
  • again_onceagain:需要适配 ipad 怎么办/
  • 超_iOS:我在一个传智的教学视频中看过一样的代码.不过那又怎样.学习了
    DXSmile:@_超 嗯我也是以前学过
  • Sanchain:请问这个item的title font可以改吗
  • Jimm_鱼:看了这边文章,就知道楼主肯定是李明杰的徒弟了。 :smile:
  • 烟佛经:图片不见了,,,关于tabbarbutton中的图片适配是怎么解决的啊,里面的图片是20*20的么?>?/
    DXSmile:@烟佛经 图片的适配问题, 你要根据tabbarbutton的自身来设置, 因为这里面是自定义了, 更换了tabbarbutton, 所以需要里面的图片也是合适的尺寸, 这个切图, 用一般UI给的 就可以的
  • 程小曦:好像是李明杰的那个思路,不过这个没有根本解决tabbbar上面的按钮对象的动画问题,自定义的还不够彻底
    DXSmile:@程小曦 是的 这个自定义目前还不彻底, 还需要进一步自定义, 因为这里是采用了修改私有方法的取巧办法, 还不是真正意义上的自定义
  • iOS_小绅士:你好.我把tabbarItem 换成了三个.左右两个是add的.中间的是利用自定义的UItabbar加的一个按钮.然后平分分布.但我发现.第一个按钮的点击区域始终占据了tabbar的一半宽度...这个问题你有遇到吗楼主
    DXSmile:@iOS_小绅士 你好 如果你是要做三个tabBarItem的话 你应该将屏幕一分为三, 左右两个用自定义的tabBarItem, 而中间的 可以加一个按钮, 用这样的方式, 就可以让每个按钮都平分了
  • 云画的跃光:你好,我想请问下,在ipad上,那四个tabbarbutton是不是也是平均分布的?我的是集中在中间
    云画的跃光:@DXSmile 嗯,知道了
    DXSmile:@云画的跃光 在iPad上 你需要做适配, 监听屏幕的旋转, 这样才能做到iPad的正取显示
  • 云画的跃光:你好,我想请教你一个问题
  • 8833b12422ad:楼主 封装通过storyboard创建NavigationController的方法这个怎么理解啊 我运行的时候DXHome 我得改成Main吗
    8833b12422ad:@DXSmile 我的是Main.storyboard 我用你的源代码运行 报了个错: 找不到一个故事板名为“DXHome”包NSBundle..... 我把DXHome 改成Main 又爆说:找不到DXMessage :cry:
    DXSmile:@goSLEEP 不需要改动了,我demo里面使用的就是DXHome. storyboard作为的首页的, 你可以在DXTabBarController类中的初始化tabBar的方法setupChildViewController看到
  • liwb:UITabBarButton 既然是私有API,调用的话,Appstore审核会通过吗?
    DXSmile:@liwb 私有属性,调用系统的私有属性,审核是过不了的, 但是如果是我们自己写的类里面的某个私有属性, 这样是没问题的
  • 随风踏叶:这样做,启动后,第一个button就不是选中状态的图片了,楼主是否注意到这个问题
    DXSmile:@随风踏叶 默认第一个选中,这个比较简单,加两句代码即可,我这里就没有写
  • 74af7fee08fd:是这样的 我按照这种方法在UITabBar里面添加了两个自定义按钮UIButton,但是有一个UIButton按钮点击之后触发的始终是他旁边的UITabBarButton,这个着实非常费解,希望能给写思路
    DXSmile:@简单不花俏 一般来说如果是自定义TabBar,都会全部使用自定义的,如果你是自定义部分item,那你需要拦截TabBar布局和赋值的两个方法,用索引判断拿到你需要的那个item,这样应该就可以了,不过这样的自定义一般很少用到,你可以尝试一下
    74af7fee08fd:@DXSmile 你没明白我的意思 我意思是底部有四个按钮 左边两个是UITabBarButton 就是系统自带的 右边两个是 我用UIButton 自定义的 没有中间那个 + 号
    DXSmile:@简单不花俏 你是直接使用的我的源码吗? 如果是的话, 你可以在里面DXTabBar.m文件中的layoutSubviews方法中,找到一行判断, 当索引为2的时候,就跳过,设置为3 , 这样做的目的是为了单独做底部中间的 + 号按钮, 你可以看一下, 这里是新浪微博的非常巧妙的地方,
  • 玉松:请问如果项目中用到了UITabBarButton 能通过苹果审核吗?谢谢
    Jimm_鱼:@玉松 楼主也不知道,因为没试过苹果审核,这边文章基本上都是李明杰讲课的视频里面原文的。
  • 小時間光:博主,图片都挂掉了,什么情况。
    DXSmile:@漓纤墨 :blush: 有时候浏览器是这样的
    小時間光:@DXSmile Safari 抽风了,换Chrome一点问题都没有。 :cold_sweat:
    DXSmile:@漓纤墨 都可以显示的 亲 :blush:
  • 努努Nunu:深夜福利
  • MrFire_:不错不错,学习了!
    DXSmile:@hungryBoy :blush:
  • SeanCST:你好,这个例子中的UITabBar中的UITabBarButton的subviews中貌似只有UITabBarSwappableImage和ViewUITabBarButtonLabel两个类的对象了,而没有UITabBarSelectionIndicatorView这个“选中”的属性了,那么如何根据获取是否选中的状态呢?比如需要根据选中状态修改ViewUITabBarButtonLabel中文字的颜色,如何实现呢?谢谢
    DXSmile:@DXSmile 当然也还有其他的方法的,我这里只是给你提供一个思路, 好像还有一种方法也可以, 那就是统一设置整个状态栏的属性, 但是这个方式下所有的状态都会是一种, 如果你需要再单独设置的话,如果将item的状态设置为UIButtonTypeCustom自定义模式,这样就可以独立设置,
    DXSmile:@肖恩Sean 首先很抱歉没有及时回复你,主要是这几天比较忙一些, 对于你提出的问题, 如何修改选中状态下的tabBarButton的属性, 这里你可以调用tabBar的代理方法来实现:<DXTabBarDelegate>, 比如这个代理里面的- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { } 这个方法, 就是在选中状态下的tabBarItem需要做的事情, 还有一种方法就是: 自定义tabBar类,使用你预先设置要的图片来代替,然后更改图片的渲染模式为原始模式:UIImageRenderingModeAlwaysOriginal, 这样同样可以达到效果, 这两种方式,你都可以尝试一下
  • Senior丶:正好需要这个,半夜能看到,实在是兴奋的不想睡了:heart_eyes::heart_eyes::heart_eyes:
    Senior丶:@DXSmile 想问一下 这个的图片的尺寸是不是固定的,能不能给个联系方式
    DXSmile:@Senior丶 :blush: 能对你有帮助就好, 如果不妥的地方,还望指正啊 :smiley:
  • 73e81a42ef46:为什么会写的这么好呢,:scream:
    DXSmile:@73e81a42ef46 呃 没有写好呢, 都被别人说没有原创性呢 :blush:
  • 蓝翔:我只能说培训机构教得好,连发个文章,都原文抄袭
    蓝翔:@DXSmile 只是说你写的东西没有原创性,并不是攻击谁,你自己去看下,类似的文章代码,简书github coding都是这些代码。
    蓝翔:@DXSmile 没有攻击你好吗? 真是小孩子。
    DXSmile:@蓝翔 我不知道你这话从何说起, 也不知道你为什么喜欢攻击人, 如果你不喜欢我发的文章, 你可以默默的离开, 不管培训机构出来的也好, 还是实际工作总结出来的也好, 我们围绕的是知识点的分享和学习, 关注的也只是技术, 或者说提升自己, 这篇文章,我非常用心的整理,也确实借鉴了之前在培训机构学习时候的一些代码和图片, 我只是想阐述明白这个知识点而已, 这有什么错吗???
    再者说了, 我们的出身确实是通过培训机构出来的, 但那又怎么了? 我们在培训机构培训那几个月, 比我再大学计算机专业几年学得东西都要多,都要用心, 都要实用, 而且当我出来工作的时候, 我就很感谢很感恩我在培训机构培训的那几个月, 没有那几个月, 也就没有我现在这么高的收入, 我为我曾经能够有幸去参加培训机构的培训而自豪!!!
    我不知道你为什么看不起培训机构, 我猜你也没有经历过正规的培训吧, 所以,你有这些怨气, 我也表示理解, 一句话结束我和你的对话: 你爱怎么说就怎么说吧, 你高兴就好!!! :blush:
  • Lonely__M:好东西,默默点个赞
    DXSmile:@Lonely__ 谢谢谢谢,多谢你的认同 :blush:
  • 明雨夏:写得很好:+1::+1::+1:
    DXSmile:@明雨夏 多谢多谢, :blush:
  • 6d9f6aa3a9d4:写的不错
    DXSmile:@yeBlueColor 多谢多谢,我还有很多不足,也需要继续探究的, :blush:
  • 黄晓坚:很棒,学习了。
    DXSmile:@黄晓坚 :blush: 共勉共勉
  • 7d9b4d7d8d6c:kvc改readonly是啥原理
    DXSmile:@Listen小华哥 上架并不会影响的
    7d9b4d7d8d6c:@DXSmile 那会影响上架嘛?
    DXSmile:@Listen小华哥 KVC做的事情,就是根据key值,给value值, 这里用KVC来更改tabBar的readonly权限,就相当于我们重新给tabBar设定了一个新的key值,从而达到修改权限的目的. 其实这个方法是有点打苹果系统擦边球的意思, 对于苹果来说,他们是不允许我们这样做的, 这里只是取巧
  • voidxin:八错八错
  • DXSmile:http://www.jianshu.com/collection/8f1ac0fd7ce4 你们也可以关注我们的"iOS移动开发社区" 这个专题, 里面收录了不少优秀的帖子,
  • iOS程序犭袁:学习下
    DXSmile:@iOS程序犭袁 共勉共勉 :blush:
  • 6461b71be67d:非常好
    DXSmile:@tyj_yy 谢谢夸奖 :smiley:
  • CaiYue_:谢谢,正需
    DXSmile:@SoledadMe 能对你有帮助就好 :smiley:
  • 李大戮:大赞
    DXSmile:@李大帅 :blush: 这篇的源码我会抽时间继续完善的,到时候请大家斧正

本文标题:你所不知道的UITabBarButton?

本文链接:https://www.haomeiwen.com/subject/ancvkttx.html