美文网首页iOS开发之实战资源ios学习iOS学霸笔记
重新认识UITabBarController,做出新浪微博标签栏

重新认识UITabBarController,做出新浪微博标签栏

作者: _奔跑的炸鸡 | 来源:发表于2016-03-14 18:59 被阅读1018次

    『微信+朋友圈』是现在常见应用社交模式的标准配置,很多应用会选择像新浪微博一样在底部提供一个标签,能够方便快捷的发布状态,那么今天我们来学习如何快速实现这个功能。

    新浪微博截图 新浪微博截图
    网上的复杂方案

    在网上找到的大部分解决方案是这样的

    1. 创建一个标签栏
    2. 给标签栏设置五个ChildViewController。
    3. 创建一个自定义的Button,大小和一个TabbarItem大小一致
    4. 调用 self.View addsubView:方法Button放到第三个TabbarItem的位置遮住它,然后给Button添加事件实现效果。

    这样做确实能实现这个功能,但是但我们需要调用poppush方法的时候,这个Button的隐藏和展示就成了麻烦事,特别是当你使用StroyBoard中的导航栏时,每次poppush都会有一个动画效果,这个Button会尤其不协调。当然,你可以通过不断修改逻辑和代码去实现,但是这里给大家介绍一种更简单的方法。


    开始前的准备

    首先准备一些标签栏用的图标,手边没有素材的可以去[阿里巴巴矢量图]下载一些使用

    准备图片

    然后创建一个新项目并把图片导入进去

    创建项目并导入图片

    创建一个继承于UITabbarController的标签栏并作为根视图控制器

    创建导航栏

    给标签栏添加视图控制器

    先给MyTabbarController添加以下方法

    - (void)addViewControllerWithTitle:(NSString *)title image:(NSString *)image 
    {
    UIViewController * vc = [[UIViewController alloc]init];
    vc.view.backgroundColor = [UIColor whiteColor];
    UINavigationController * nav = [[UINavigationController alloc]initWithRootViewController:vc];
    [self addChildViewController:nav];
    nav.title = title;
    nav.tabBarItem.image = [UIImage imageNamed:image];
    }
    

    在ViewDidLoad中调用这个方法

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.tabBar.tintColor = ColorFromRGB(0xEA8010);
    [self addViewControllerWithTitle:@"首页" image:@"tab_index"];
    [self addViewControllerWithTitle:@"消息" image:@"tab_message"];
    
    UIViewController * vc = [UIViewController new];
    [self addChildViewController:vc];
    vc.tabBarItem.image = [[UIImage imageNamed:@"tab_release"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    vc.tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -5, 0);
    
    [self addViewControllerWithTitle:@"发现" image:@"tab_discover"];
    [self addViewControllerWithTitle:@"我的" image:@"tab_mine"];
    
    }
    

    哦对了,你还需要这个宏来将一个十六进制的颜色转化成UIColor对象

    #define ColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
    

    运行看看效果

    运行效果
    使用标签栏的误区

    我们都知道每一个UITabBarItem都有一个image属性和selectedImage属性,分别对应未选中状态下的图片和选中状态下的图片。
    我们还知道UITabBar有一个属性叫做tintColor,表示当某个TabBarItem处于高亮状态下时的颜色。
    那么他们究竟有什么区别呢?
    我们先从上面代码中那句
    [[UIImage imageNamed:@"tab_release"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]说起
    这个RenderingMode的参数需要一个UIImageRenderingMode类型的参数,这是一个枚举类型,字面意思为图片渲染模式,它的枚举值如下

    UIImageRenderingMode
    可以看到,有三个模式,分别为自动,始终原样不动以及始终按照模板渲染,默认是自动。
    那么什么是按照模板渲染呢?
    这就说到了标签栏处理图片的方式,对于任意一张加载UITabBarItem上的图片,在未选中下是灰色的,无论你使用什么颜色的图片,选中状态下是蓝色的,无论你使用什么颜色的图片。这就是所谓按照模板渲染,标签栏给每一张图片都照着这个过程去渲染,通过改变tintColor就可以改变选中状态下的颜色。而且在默认状态下,如果没有设置selectedImage,那么选中时的图片会使用UITabBarItemimage所使用的图片。

    因此,设置一个标签栏只需要设置它每个TabbarItemTitle``image,然后设置TabBartintColor即可。因为即使你在设置选中图片颜色的时候设定参数UIImageRenderingModeAlwaysOriginal,你不还有一个文字颜色要改嘛?还是得设置tintColor的值

    那么这个image属性和selectedImage属性还有用吗?
    答案是,有用。
    记得天猫美团支付宝这些APP每到逢年过节做的那些花里胡哨的界面吗?假设你的标签栏上是四只猴子,未选中就蹲着,选中就站起来,而且猴子的颜色很丰富,这个时候你就会用到imageselectImage,而且记得要把加工模式设置为UIImageRenderingModeAlwaysOriginal

    SO,如果你的项目只是一个传统的标签栏,那么问美工要切图的时候就可以跟他说,"你就搞个形状给我就行了,颜色劳资自己搞定╭(′▽`)╯"

    回到我们的程序,中间的TabBarItem我们就将其图片的渲染模式设置为UIImageRenderingModeAlwaysOriginal,这样它即使在未选中状态下,依然会是橘黄色。我们不给它加标题,并且调整一下它的位置,这样就有了中间的按钮。

    创建发布消息页面

    我们首先创建一个发布消息的UIView

    创建发布消息的界面

    Release.h中这么写
    @interface ReleaseView : UIView
    @property(nonatomic,strong)UIVisualEffectView * effectView;
    @end

    Release.m中这样写
    - (instancetype)initWithFrame:(CGRect)frame
    {
    if (self = [super initWithFrame:frame]) {
    UIBlurEffect * effrct = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    _effectView = [[UIVisualEffectView alloc]initWithEffect:effrct];
    _effectView.frame = self.bounds;
    [self addSubview:_effectView];

        UIButton * cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        cancelBtn.frame = CGRectMake(self.bounds.size.width / 5 * 2, self.bounds.size.height - 49 , 40, 40);
        
        cancelBtn.center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height - 49);
        [self addSubview:cancelBtn];
        [cancelBtn setBackgroundImage:[UIImage imageNamed:@"release_cancel"] forState:UIControlStateNormal];
        
        [cancelBtn addTarget:self action:@selector(cancelBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
    }
    - (void)cancelBtnClicked:(UIButton *)btn
    {
    self.hidden = YES;
    }
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
    self.hidden = YES;
    }
    

    UIVisualEffectView是iOS 8.0之后提供的一种用来快速实现半透明效果的视图,通过如上所示的三行代码就可以轻松创建一个半透明的蒙版,它提供三种风格,分别是Light,ExLight和Dark,具体效果大家可以自己试验。

    实现最终效果

    回到我们的标签栏,将刚才创建的ReleaseView头文件引入
    #import "ReleaseView.h"
    添加为成员属性
    @property(nonatomic,strong)ReleaseView * releaseView;

    ViewDidLoad中添加代码

    - (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    ....
    _releaseView = [[ReleaseView alloc]initWithFrame:self.view.bounds];
    _releaseView.hidden = YES;
    [self.view addSubview:_releaseView];
    ....
    }
    

    接下来是另一个很重要的步骤,重写setSelectedViewController:(__kindof UIViewController *)selectedViewController方法
    - (void)setSelectedViewController:(__kindof UIViewController *)selectedViewController
    {
    if ([selectedViewController class] == [UIViewController class]) {
    _releaseView.hidden = NO;
    }
    else
    {
    [super setSelectedViewController:selectedViewController];
    }
    }

    这里我们给其他TabBarItem对应的都是一个导航栏控制器,只有中间这个是个普通的视图控制器,因此可以这么作比较,实际项目中每个标签对应的一定是不一样的视图控制器,因此根据实际情况写即可。

    为什么是setSelectedViewController: 不是setSelectedIndex:

    有些同学可能注意到了,标签栏有setSelectedViewController:setSelectedIndex:两个方法。那么为什么重写的是前一个呢?
    因为当我们主动点击某个标签时调用的就是前一个方法。
    那么后一个方法什么时候调用呢?
    后一个方法其实是留给开发者使用的一个接口,用来自动跳转到某个标签栏。比如我们可以在调用[self setSelectedIndex:1];让APP一开始就显示第三个标签栏。而这个方法内部其实还是调用了setSelectedViewController:去执行。

    运行看效果
    运行效果
    结束

    到此为止,我们已经完成了新浪微博标签栏的制作,至于要往这个半透明的发布页面加什么功能,就凭大家发挥了。

    相关文章

      网友评论

      本文标题:重新认识UITabBarController,做出新浪微博标签栏

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