UI篇-UITabBar及其相关其他知识

和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换。

UITabBarController的视图结构如下;

Paste_Image.png
  • UITabBar
    下方的工具条称为UITabBar ,如果UITabBarController有N个子控制器,那么UITabBar内部就会有N 个UITabBarButton作为子控件与之对应。
    注意:UITabBarButton在UITabBar中得位置是均分的,UITabBar的高度为49。
    在上面的程序中,UITabBarController有4个子控制器,所以UITabBar中有4个UITabBarButton,UITabBar的结构⼤大致如下图所示:
  • UITabBarButton
    UITabBarButton⾥面显⽰什么内容,由对应子控制器的tabBarItem属性来决定
    c1.tabBarItem.title=@"消息"; c1.tabBarItem.image=[UIImage imageNamed:@"tab_recent_nor"];
  • 有两种方式可以往UITabBarController中添加子控制器

    (1)[tb addChildViewController:c1];
    (2)tb.viewControllers=@[c1,c2,c3,c4];

  • selectedIndex属性
    通过该属性可以获得当前选中的viewController 的下标,以及手动切换子视图。

  • selectedViewController属性
    通过该属性可以获得当前选中的viewController,一般直接获得是 UINavigationController。
    每个视图控制器都有一个tabBarController属性,通过它可以访问所在的UITabBarController
    每个视图控制器都有一个tabBarItem属性,通过它控制视图在UITabBarController的tabBar中的显示信息。

系统自带的TabBar

UITabBarController 中:

   ViewController *vc1=[[ViewController alloc] init];
   vc1.tabBarItem.title=@"首页";
   vc1.tabBarItem.image=[[UIImage imageNamed:@"111N"]
   imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
   vc1.tabBarItem.selectedImage=[[UIImage imageNamed:@"111L"]
      imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    BHHHViewController *vc2=[[BHHHViewController alloc] init];
    vc2.tabBarItem.title=@"排行";
    vc2.tabBarItem.image=[[UIImage imageNamed:@"222N"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    vc2.tabBarItem.selectedImage=[[UIImage imageNamed:@"222L"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
   
    UINavigationController *nav1=[[UINavigationController alloc] initWithRootViewController:vc1];
    UINavigationController *nav2=[[UINavigationController alloc] initWithRootViewController:vc2];
    self.viewControllers=@[nav1,nav2];

设置TabBar背景颜色

tabBar和navigationBar 设置这个线的颜色都是使用 setShadowImage 这个方法.

方法-:
    self.tabBar.barTintColor = [UIColor blueColor];;//这样是也可以修改颜色

方法二:
     UIView *backView = [[UIView alloc]  initWithFrame:CGRectMake(0, 0, WIDTH, Scale_Y(49))];
    backView.backgroundColor = RGB(248, 150, 68, 1);
    [self.tabBar insertSubview:backView atIndex:0];
    self.tabBar.opaque = YES;

设置TabBar顶部细线的颜色

 UIImageView  *navBarHairlineImageView = [[MethodTool shareTool] findHairlineImageViewUnder:self.tabBar];
 navBarHairlineImageView.hidden = YES;

    //设置背景颜色或图片
    [self.tabBar setBackgroundImage:[[MethodTool shareTool]imageWithColor:[UIColor whiteColor] size:CGSizeMake(WIDTH, 49)]];
     //设置顶部细线的颜色
    [self.tabBar setShadowImage:[[MethodTool shareTool]imageWithColor:ViewlineColor size:CGSizeMake(WIDTH, 0.5)]];
     //设置点击后的选中 item 背景颜色
    [self.tabBar setSelectionIndicatorImage:[[MethodTool shareTool]imageWithColor:[UIColor redColor] size:CGSizeMake(WIDTH/3, 49)]];

//*********************************
  - (UIImageView *)findHairlineImageViewUnder:(UIView *)view {
    if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) {
        return (UIImageView *)view;
    }
    for (UIView *subview in view.subviews) {
        UIImageView *imageView = [self findHairlineImageViewUnder:subview];
        if (imageView) {
            return imageView;
        }
    }
        return nil;
  }

设置TabBar下面的字体在不同状态下的颜色:

    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor blackColor], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
    [[UITabBarItem appearance] setTitleTextAttributes:  [NSDictionary dictionaryWithObjectsAndKeys:[UIColor redColor] ,NSForegroundColorAttributeName, nil]forState:UIControlStateSelected];

NSForegroundColorAttributeName 是iOS7.0之后才使用的,之前是 UITextAttributeTextColor,关于弃用后如何找到一个替代者,其实很简单,认真阅读:


弃用.png

系统自带的TabBar 中关于底部Bar的隐藏问题和返回展现的最简单的方法:

1. 在 BaseViewController 里面的 ViewDidLoad里面设置
 if (self.navigationController.viewControllers.count>1) {
    self.hidesBottomBarWhenPushed = YES;
 }

//如果在push跳转时需要隐藏tabBar,需要在最外层的VC中跳转之前设置
// block 回调中跳转   需要紧紧写在跳转的前后
self.hidesBottomBarWhenPushed=YES;
NextViewController *next=[[NextViewController alloc]init];
[self.navigationController pushViewController:next animated:YES];
self.hidesBottomBarWhenPushed=NO;
//这样back回来的时候,tabBar会恢复正常显示。

2. 只需在第一层页面向第二层页面跳转的地方设置一次即可,第二层向第三层跳转时不需要再次设置,当然,想在第三层页面上显示出 tabbar,设置.hidesBottomBarWhenPushed = NO也是不可能的出效果的。
 NextViewController *next=[[NextViewController alloc]init];
 next.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:next animated:YES];

3.在 BaseViewController 里面的 init方法里面设置如下:也可以达到特定页面隐藏  tabbar 的效果。(只要在 push前设定 nextView 的hidesBottomBarWhenPushed属性才可以有效果,在 push 方法之后的设置都不行,init 方法在 push 方法之前执行)
    if ([NSStringFromClass(self.class) isEqualToString:@"IndexViewController"]||[NSStringFromClass(self.class) isEqualToString:@"MedicalViewController"]) {
         self.hidesBottomBarWhenPushed = NO;
    }else{
         self.hidesBottomBarWhenPushed = YES;
    }


4. for in 的方法找到  UITabbar  ,手动隐藏和展现,效果图如下:
  -(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self hideTabBar];
}

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
   [self showTabBar];
}
-(void)hideTabBar{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    for(UIView *view in self.tabBarController.view.subviews)
    {
        if([view isKindOfClass:[UITabBar class]])
        {
            [view setFrame:CGRectMake(view.frame.origin.x, HEIGHT, view.frame.size.width, view.frame.size.height)];
        
        }else
        {
            [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
        }
    }
    [UIView commitAnimations];
 }

-(void)showTabBar {
    [UIView beginAnimations:nil context:NULL];
   [UIView setAnimationDuration:0.5];

    for(UIView *view in self.tabBarController.view.subviews)
    {
    
    NSLog(@"%@",view);
    if([view isKindOfClass:[UITabBar class]])
    {
        [view setFrame:CGRectMake(view.frame.origin.x, HEIGHT-49, view.frame.size.width, view.frame.size.height)];
        view.hidden = NO;
    }else
    {
        [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
    }
}
[UIView commitAnimations];
}
hideTabbar.gif

关于隐藏底部的Tabbar 推荐使用第二种方法,最方便快捷。

自定义TbarBar 视图切换时的动画的关键方法(后续会整理出视图切换时的动画实现)

  - (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
        animationControllerForTransitionFromViewController:(UIViewController *)fromVC
                                          toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);
{
    return ani;
}

其他相同的用法还有很多:

   <UINavigationControllerDelegate>
 - (nullable id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                        animationControllerForOperation:(UINavigationControllerOperation)operation
                                                     fromViewController:(UIViewController *)fromVC
                                                       toViewController:(UIViewController *)toVC
{ if(operation==UINavigationControllerOperationPush)
   { if(fromVC==self)
       {
      return ani;
      } }
    return nil;
 }

这里的ani 是一个遵从<UIViewControllerAnimatedTransitioning>的类对象。

UIAppearance是一个协议,UIView默认已经遵守了这个协议。

  @protocol UIAppearance <NSObject>
  UIView 默认遵从 UIAppearance 协议
让某一类控件在另一种控件中同时变现某种属性

[[UIButton appearanceWhenContainedInInstancesOfClasses:@[[UIView class]]] setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];

上面这句话的意思 就是—-使UIView上面的UIButton的titleColor都变成灰色, 
而且作用域是整个工程, 也就是说,不管在工程中的哪个位置写下这句代码,
整个工程中的按钮的字体颜色都会变成灰色**

Tbbar 点击时图标加动画

注意,UITabbarViewController中已经实现了 UITabBarDelegate,如果再次设置 self.tabbar.delegate = self;会造成程序崩溃,并且 UITabbarViewController中 tabbar 是一个 只读的属性,不能再次操作。

//会被自动调用
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{

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

推荐阅读更多精彩内容