• iOS 自定义TabBarController


    转自:http://blog.csdn.net/xn4545945/article/details/35994863

    一、自定义的思路

    iOS中的TabBarController确实已经很强大了,大部分主流iOS应用都会采用。但是往往也不能满足全部的需求,因此需要自定义TabBar,自定义需要对系统的TabBar工作方式有很好的理解,自定义需要勇气。

    自定义TabBar的原则:尽量利用系统自带TabBar,只改需要改的地方。


    二、自定义TabBar的总体过程
    1.先把自带的TabBar条给取消了
    2.自己做一个view,上面放几个按钮,设定按钮的点击事件.并设置selectIndex。
    3.关联各个子viewController,覆盖相关事件。

    三、细节很重要

    1. 让自己创建的按钮关联到viewController:
    •用tabbar的selectedIndex属性.设置这个属性就行了.
    2. 取消系统的高亮:
    •可以自定义一个按钮.重写里面的setHighhighted方法,什么也不做就行了.(如果调用super就相当于没写)
    3. 关于几个按钮只选中一个的方法:
    •设置一个属性,记录上一个选中的按钮.
    •点击当前按钮时,把上一个按钮设置为未选中,并把当前按钮设置为选中,最后把当前按钮赋值给上一个按钮.

    四、初步自定义
    直接上代码,详见注释。
     

    XNTabBarController.h

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. #import <UIKit/UIKit.h> @interface @end  

    XNTabBarController.m

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. // //  XNTabBarController.m // // //  Created by neng on 14-6-19. //  Copyright (c) 2014年 neng. All rights reserved. // #import "XNTabBarController.h" #import "Common.h" #import "XNTabBarButton.h" @interface /** 
    2.  *  设置之前选中的按钮 
    3.  */ @propertynonatomicUIButton @end @implementation void super];  
    4.   
    5. //    NSLog(@"%s",__func__); //    NSLog(@"%@",self.view.subviews); //能打印出所有子视图,和其frame self);  
    6.   
    7. self.frame self removeFromSuperview  
    8.   
    9. UIView]];  
    10.  = rect;  
    11.  = [UIColor];  
    12. self addSubview forint; i < ; i++) {  
    13.   
    14. XNTabBarButton]];  
    15. NSString:, i +];  
    16. NSString:, i +];  
    17. :[UIImage:imageName]:UIControlStateNormal];  
    18. :[UIImage:imageNameSel]:UIControlStateSelected];  
    19. i.size / ;  
    20.  = CGRectMake(x, , myView.size / , myView.size);  
    21. :btn];  
    22.  = i;  
    23.   
    24. :self:@selector forControlEvents   
    25. if == i) {  
    26.  = YES self = btn;    
    27. /** 
    28.  *  自定义TabBar的按钮点击事件 
    29.  */ voidUIButton   
    30. self.selectedNO   
    31.  = YES   
    32. self = button;  
    33.   
    34. self = button;  
    35. @end  

    XNTabBarButton.h

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. #import <UIKit/UIKit.h> @interface @end  

    XNTabBarButton.m

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. #import "XNTabBarButton.h" @implementation /**什么也不做就可以取消系统按钮的高亮状态*/ voidBOOL //    [super setHighlighted:highlighted]; @end  


    五、代码重构

    重构的目的是把代码放到他最该到的地方去. 提高可读写与可拓展性。

    对控件的重构要保证可重用性. 做到封装做其他应用时,可以直接拿过去用的地步.

    tips :
     
    1、关于init与initWithFrame:
    •在对象初始化调用init时,会调用initWithFrame方法.
    •Init与initWithFrame都会被调用.
    •建议自定义控件不要重写init方法,需要初始化时重写initWithFrame方法.
    •好处:其他人调用无论是调用init,还是调用initWithFrame都会调用initWithFrame方法.
    2、关于控件的布局代码:
    •建议写在layoutSubviews方法中.
    •不要忘记写super方法
    •将设置x,y,frame等写在这里面.
    3、将自定义的Tabbar添加为系统TabBar的子视图,这样TabBar的切换自动隐藏/滑动功能就不用自己做了. (hidebottombaronpush)

    重构后的代码如下
    将自定义的TabBar单独建立,并将代码移过去。
    设置代理方法,工具栏按钮被选中,记录从哪里跳转到哪里. 

    XNTabBar.h

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. #import <UIKit/UIKit.h> @class @protocol /** 
    2.  *  工具栏按钮被选中, 记录从哪里跳转到哪里. (方便以后做相应特效) 
    3.  */ void tabBarXNTabBar:(NSInteger) from:(NSInteger)to;  
    4. @end @interface @propertynonatomicid /** 
    5.  *  使用特定图片来创建按钮, 这样做的好处就是可扩展性. 拿到别的项目里面去也能换图片直接用 
    6.  * 
    7.  *  @param image         普通状态下的图片 
    8.  *  @param selectedImage 选中状态下的图片 
    9.  */ voidUIImage:(UIImage @end  


    XNTabBar.m


    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. // //  XNTabBar.m // //  Created by neng on 14-6-19. //  Copyright (c) 2014年 neng. All rights reserved. // #import "XNTabBar.h" #import "XNTabBarButton.h" @interface /** 
    2.  *  设置之前选中的按钮 
    3.  */ @propertynonatomicUIButton @end @implementation /** 
    4.  *  在这个方法里写控件初始化的东西, 调用init方法时会调用 
    5.  */ //- (id)initWithFrame:(CGRect)frame { //  if (self = [super initWithFrame:frame]) { //      //添加按钮 //      for (int i = 0; i < 5; i++) { //取消掉特定的数字 //          //UIButton *btn = [[UIButton alloc] init]; //          XNTabBarButton *btn = [[XNTabBarButton alloc] init]; // //          NSString *imageName = [NSString stringWithFormat:@"TabBar%d", i + 1]; //          NSString *imageNameSel = [NSString stringWithFormat:@"TabBar%dSel", i + 1]; // //          [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; //          [btn setImage:[UIImage imageNamed:imageNameSel] forState:UIControlStateSelected]; // //          [self addSubview:btn]; // //          btn.tag = i; //设置按钮的标记, 方便来索引当前的按钮,并跳转到相应的视图 // //          //带参数的监听方法记得加"冒号" //          [btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside]; // //          if (0 == i) { //              [self clickBtn:btn]; //          } //      } //  } //  return self; //} voidUIImage:(UIImage UIButton]];  
    6. :image:UIControlStateNormal];  
    7. :selectedImage:UIControlStateSelected];  
    8. self:btn];  
    9.   
    10. :self:@selector forControlEvents   
    11. ifself.count) {  
    12. self:btn];  
    13. /**专门用来布局子视图, 别忘了调用super方法*/ void super];  
    14. intself.count forint; i < count; i++) {  
    15.   
    16. UIButtonself[i];  
    17.  = i;   
    18. iself.size / count;  
    19. ;  
    20. self.size / count;  
    21. self.size;  
    22.  = CGRectMake(x, y, width, height);  
    23. /** 
    24.  *  自定义TabBar的按钮点击事件 
    25.  */ voidUIButton   
    26. self.selectedNO   
    27.  = YES   
    28. self = button;  
    29.   
    30.   
    31. ifself respondsToSelector@selector self tabBarself:self.tag:button];  
    32.   
    33.   
    34. @end  


    原先的XNTabBarController.m经过修改后,注释了原先的代码。

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    1. // //  XNTabBarController.m // //  Created by neng on 14-6-19. //  Copyright (c) 2014年 neng. All rights reserved. // #import "XNTabBarController.h" #import "XNTabBarButton.h" #import "XNTabBar.h" @interface /** 
    2.  *  设置之前选中的按钮 
    3.  */ @propertynonatomicUIButton @end @implementation void super];  
    4.   
    5. //    NSLog(@"%s",__func__); //    NSLog(@"%@",self.view.subviews); //能打印出所有子视图,和其frame //  LogFun; //  LogSubviews(self.view);   
    6.   
    7. self.bounds  
    8. self);  
    9.   
    10.   
    11. XNTabBar]];   
    12.  = self  
    13.  = rect;  
    14. self addSubview  
    15.   
    16. forint; i<self.count  
    17. NSString:, i +];  
    18. NSString:, i +];  
    19. UIImage:imageName];  
    20. UIImage:imageNameSel];  
    21. :image:imageSel];  
    22. //    //添加按钮 //  for (int i = 0; i < 5; i++) { //      //UIButton *btn = [[UIButton alloc] init]; //        XNTabBarButton *btn = [[XNTabBarButton alloc] init]; // //      NSString *imageName = [NSString stringWithFormat:@"TabBar%d", i + 1]; //      NSString *imageNameSel = [NSString stringWithFormat:@"TabBar%dSel", i + 1]; // //      [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; //      [btn setImage:[UIImage imageNamed:imageNameSel] forState:UIControlStateSelected]; // //      CGFloat x = i * myView.frame.size.width / 5; //      btn.frame = CGRectMake(x, 0, myView.frame.size.width / 5, myView.frame.size.height); // //      [myView addSubview:btn]; // //        btn.tag = i;//设置按钮的标记, 方便来索引当前的按钮,并跳转到相应的视图 // //      //带参数的监听方法记得加"冒号" //      [btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside]; // //      //设置刚进入时,第一个按钮为选中状态 //      if (0 == i) { //          btn.selected = YES; //          self.selectedBtn = btn;  //设置该按钮为选中的按钮 //      } //  } /**永远别忘记设置代理*/ voidXNTabBar:(NSInteger)from:(NSInteger)to {  
    23. self = to;  
    24. /** 
    25.  *  自定义TabBar的按钮点击事件 
    26.  */ //- (void)clickBtn:(UIButton *)button { //  //1.先将之前选中的按钮设置为未选中 //  self.selectedBtn.selected = NO; //  //2.再将当前按钮设置为选中 //  button.selected = YES; //  //3.最后把当前按钮赋值为之前选中的按钮 //  self.selectedBtn = button; // //    //4.跳转到相应的视图控制器. (通过selectIndex参数来设置选中了那个控制器) //    self.selectedIndex = button.tag; //} @end  


    自定义后的效果图:




    例子源码下载  http://download.csdn.net/detail/xn4545945/7572263

    转载请注明出处:http://blog.csdn.net/xn4545945  

  • 相关阅读:
    C#调用C++ memcpy实现各种参数类型的内存拷贝 VS marshal.copy的实现 效率对比
    UGUI 事件穿透规则
    UGUI 锚点设置为四方扩充模式然后设置局部坐标为0将出现什么问题
    UNITY polygon collider不随物体旋转
    android Handler机制 消息机制
    java final finally finalize
    collection 和 collections
    java 不通过第三个字符串,实现一个字符串倒序
    ArrayList,Vector,LinkedList
    String StringBuffer stringbuilder 区别
  • 原文地址:https://www.cnblogs.com/feiyu-mdm/p/5568595.html
Copyright © 2020-2023  润新知