Emo_Lin

iOS - 初级封装

【浅学封装思想】

 

实例壹:创建微博框架。首先是创建一个UITabBarController,在下面显示栏再创建四个 UIViewController。如下四个文本:

 

1 //  AppDelegate.h - 版本1
2 //  Emo微博
3 
4 #import <UIKit/UIKit.h>
5 
6 @interface AppDelegate : UIResponder <UIApplicationDelegate>
7 @property (strong, nonatomic) UIWindow *window;
8 @end

 

 1 //  AppDelegate.m - 版本1
 2 //  Emo微博
 3 
 4 #import "AppDelegate.h"
 5 #import "EmoTabBarController.h"
 6 // 封装思想:如果以后项目中,有相同的功能,抽取一个类,封装好,如何封装,自己的事情全部交给自己管理。
 7 // 抽方法:一般一个功能就抽一个方法。
 8 
 9 @interface AppDelegate ()
10 @end
11 
12 @implementation AppDelegate
13 
14 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
15     // Override point for customization after application launch.
16     
17     // 创建窗口
18     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
19     // 创建tabBarVc
20     EmoTabBarController *tabBarVc = [[EmoTabBarController alloc] init];
21     // 设置窗口的根控制器
22     self.window.rootViewController = tabBarVc;
23     // 显示窗口
24     [self.window makeKeyAndVisible];
25     
26     return YES;
27 }
28 @end

 

1 //  EmoTabBarController.h - 版本1
2 //  Emo微博
3 
4 #import <UIKit/UIKit.h>
5 
6 @interface EmoTabBarController : UITabBarController
7 @end

 

 1 //  EmoTabBarController.m - 版本1
 2 //  Emo微博
 3 #import "EmoTabBarController.h"
 4 
 5 @interface EmoTabBarController()
 6 @end
 7 
 8 @implementation EmoTabBarController
 9 
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12     [self setUpAllChildViewController];
13 }
14 
15 - (void)setUpAllChildViewController
16 {
17 
18     // 首页
19     UIViewController *home = [[UIViewController alloc] init];
20     home.tabBarItem.title = @"首页";
21     home.tabBarItem.image = [UIImage imageNamed:@"tabbar_home"];
22  // home.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_home_selected"];//仅仅是这句话那么图片控件会被系统默认为是蓝色。
23     UIImage*selImage = [UIImage imageNamed:@"tabbar_home_selected"];
24     selImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
25     home.tabBarItem.selectedImage =selImage;
26     home.view.backgroundColor = [UIColor greenColor];
27     [self addChildViewController:home];  
28 
29     // 消息
30     UIViewController *message = [[UIViewController alloc] init];
31     message.tabBarItem.title = @"消息";
32     message.view.backgroundColor = [UIColor blueColor];
33     message.tabBarItem.image = [UIImage imageNamed:@"tabbar_message"];
34     UIImage*selImage = [UIImage imageNamed:@"tabbar_message_selected"];
35     selImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
36     home.tabBarItem.selectedImage =selImage;
37     [self addChildViewController:home];      
38 
39     // 发现
40     UIViewController *discover= [[UIViewController alloc] init];
41     discover.tabBarItem.title = @"发现";
42     discover.view.backgroundColor = [UIColor redColor];
43     discover.tabBarItem.image = [UIImage imageNamed:@"tabbar_discover"];
44     UIImage*selImage = [UIImage imageNamed:@"tabbar_discover_selected"];
45     selImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
46     discover.tabBarItem.selectedImage =selImage;
47     [self addChildViewController:home];   
48 
49     //
50     UIViewController *profile= [[UIViewController alloc] init];
51     profile.tabBarItem.title = @"";
52     profile.view.backgroundColor = [UIColor blueColor];
53     profile.tabBarItem.image = [UIImage imageNamed:@"tabbar_profile"];
54     UIImage*selImage = [UIImage imageNamed:@"tabbar_profile_selected"];
55     selImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
56     discover.tabBarItem.selectedImage =selImage;
57     [self addChildViewController:home];   
58 
59 }
60 @end

 

实例贰:倘若把下面这一段单独抽取出来写成分类,

 1 //  EmoTabBarController.m
 2 //  Emo微博
...
23     UIImage*selImage = [UIImage imageNamed:@"tabbar_home_selected"];
24     selImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
25     home.tabBarItem.selectedImage =selImage;

可以先创建一个分类“UIImage+Image”

 

1 //  UIImage+Image.h - 版本1
2 //  Emo微博
3 
4 #import <UIKit/UIKit.h>
5 
6 @interface UIImage (Image)
7 + (instancetype)imageWithOriginalName:(NSString *)imageName;
8 @end

 

 1 //  UIImage+Image.m - 版本1
 2 //  Emo微博
 3 
 4 #import "UIImage+Image.h"
 5 @implementation UIImage (Image)
 6 
 7 // 抽取出来后改写为“+ (instancetype)imageWithOriginalName:(NSString *)imageName”
 8 // UIImage*selImage = [UIImage imageNamed:@"tabbar_home_selected"];
 9 // selImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
10 // home.tabBarItem.selectedImage =selImage;
11 
12 + (instancetype)imageWithOriginalName:(NSString *)imageName
13 {
14     UIImage *image = [UIImage imageNamed:imageName];
15     return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
16 }
17 
18 @end

 

在“EmoTabBarController.m”中抽取出来后,替换上面的” EmoTabBarController.m“为如下代码:

 

 1 //  EmoTabBarController.m - 版本2
 2 //  Emo微博
 3 
 4 #import "EmoTabBarController.h"
 5 #import "UIImage+Image.h"
 6 
 7 @interface EmoTabBarController ()
 8 @end
 9 
10 @implementation EmoTabBarController
11 
12 - (void)viewDidLoad {
13     [super viewDidLoad];
14     // Do any additional setup after loading the view.
15     
16     // 添加所有子控制器
17     [self setUpAllChildViewController];
18 
19 }
20 // 在ios7之后,默认会把UITabBar上面的按钮图片渲染成蓝色
21 #pragma mark - 添加所有的子控制器
22 - (void)setUpAllChildViewController
23 {
24     // 首页
25     UIViewController *home = [[UIViewController alloc] init];
26     home.tabBarItem.title = @"首页";
27     home.tabBarItem.image = [UIImage imageNamed:@"tabbar_home"];
28     // 调用子类"UImage+image“的方法”imageWithOriginalName“并传入参数
29     home.tabBarItem.selectedImage = [UIImage imageWithOriginalName:@"tabbar_home_selected"];
30     home.view.backgroundColor = [UIColor greenColor];
31     [self addChildViewController:home];
32     
33     // 消息
34     UIViewController *message = [[UIViewController alloc] init];
35     message.tabBarItem.title = @"首页";
36     message.tabBarItem.image = [UIImage imageNamed:@"tabbar_message"];
37     message.tabBarItem.selectedImage = [UIImage imageWithOriginalName:@"tabbar_message_selected"];
38     message.view.backgroundColor = [UIColor greenColor];
39     [self addChildViewController:message];
40     
41     // 发现
42     UIViewController *discover = [[UIViewController alloc] init];
43     discover.tabBarItem.title = @"首页";
44     discover.tabBarItem.image = [UIImage imageNamed:@"tabbar_discover"];
45     discover.tabBarItem.selectedImage = [UIImage imageWithOriginalName:@"tabbar_discover_selected"];
46     discoverview.backgroundColor = [UIColor greenColor];
47     [self addChildViewController:discover];
48     
49     //
50     UIViewController *profile = [[UIViewController alloc] init];
51     profile.tabBarItem.title = @"首页";
52     profile.tabBarItem.image = [UIImage imageNamed:@"tabbar_profile"];
53     profile.tabBarItem.selectedImage = [UIImage imageWithOriginalName:@"tabbar_profile_selected"];
54     profile.view.backgroundColor = [UIColor greenColor];
55     [self addChildViewController:profile ];
56 }
57 
58 @end

 

实例叁:再看看下面这一部分代码:

24     // 首页
25     UIViewController *home = [[UIViewController alloc] init];
26     home.tabBarItem.title = @"首页";
27     home.tabBarItem.image = [UIImage imageNamed:@"tabbar_home"];
28     // 调用子类"UImage+image“的方法”imageWithOriginalName“并传入参数
29     home.tabBarItem.selectedImage = [UIImage imageWithOriginalName:@"tabbar_home_selected"];
30     home.view.backgroundColor = [UIColor greenColor];
31     [self addChildViewController:home];

其实都是在添加一个子控制器,所以可以抽取出一个方法且加入参数让其传进来,所以代码可以修改为:

 

 1 //  EmoTabBarController.m - 版本3
 2 //  传智微博
 3 
 4 
 5 #import "EmoTabBarController.h"
 6 #import "UIImage+Image.h"
 7 
 8 @interface EmoTabBarController ()
 9 @end
10 
11 @implementation EmoTabBarController
12 
13 - (void)viewDidLoad {
14     [super viewDidLoad];
15     // Do any additional setup after loading the view.
16     
17     // 添加所有子控制器
18     [self setUpAllChildViewController];
19 
20 }
21 
22 // 如果通过模型设置控件的文字颜色,只能通过文本属性(富文本:颜色,字体,空心,阴影,图文混排)
23 // 在ios7之后,默认会把UITabBar上面的按钮图片渲染成蓝色
24 #pragma mark - 添加所有的子控制器
25 - (void)setUpAllChildViewController
26 {
27     // 首页
28     UIViewController *home = [[UIViewController alloc] init];
29     // imageWithOriginalName:这个参数只能改变选中的按钮图片不为系统默认的蓝色,但是按钮的文字改不了,要在下面的封装部分修改。
30     [self setUpOneChildViewController:home image:[UIImage imageNamed:@"tabbar_home"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_home_selected"] title:@"首页"];
31     home.view.backgroundColor = [UIColor greenColor];
32     
33     // 消息
34     UIViewController *message = [[UIViewController alloc] init];
35     [self setUpOneChildViewController:message image:[UIImage imageNamed:@"tabbar_message_center"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_message_center_selected"] title:@"消息"];
36     message.view.backgroundColor = [UIColor blueColor];
37     
38     // 发现
39     UIViewController *discover = [[UIViewController alloc] init];
40     [self setUpOneChildViewController:discover image:[UIImage imageNamed:@"tabbar_discover"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_discover_selected"] title:@"发现"];
41     discover.view.backgroundColor = [UIColor purpleColor];
42     
43 
44     //
45     UIViewController *profile = [[UIViewController alloc] init];
46     [self setUpOneChildViewController:profile image:[UIImage imageNamed:@"tabbar_profile"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_profile_selected"] title:@""];
47     profile.view.backgroundColor = [UIColor lightGrayColor];
48 }
49 
50 #pragma mark - 添加一个子控制器
51 - (void)setUpOneChildViewController:(UIViewController *)vc image:(UIImage *)image selectedImage:(UIImage *)selectedImage title:(NSString *)title
52 {
53     // 待传进标题
54     vc.tabBarItem.title = title;
55     // 待传进正常状态下的图片
56     vc.tabBarItem.image = image;
57     // 下面三行是让按钮的文字也变成窗口的颜色
58     NSMutableDictionary *att = [NSMutableDictionary dictionary];
// [NSForegroundColorAttributeName]传key,[UIColor orangeColor]传 value。
59 att[NSForegroundColorAttributeName] = [UIColor orangeColor]; 60 [vc.tarBarItem.setTitleTextAttributes:att forState: UIControlStateSelected]; 61 // 让所有子控制器都显示10条显示 62 vc.tabBarItem.badgeValue = @"10"; 63 // 传进选中时显示的图片 64 vc.tabBarItem.selectedImage = selectedImage; 65 66 [self addChildViewController:vc]; 67 } 68 69 @end

 

实例肆:接着看看修改过的” EmoTabBarController.m“,其实下面这段代码还可以再做封装。

57     // 下面三行是让按钮的文字也变成窗口的颜色
58     NSMutableDictionary *att = [NSMutableDictionary dictionary];
59     [att setObject:[UIColor orangeColor] forKey:NSForegroundColorAttributeName];
60     [vc.tarBarItem.setTitleTextAttributes:att forState: UIControlStateSelected];

用全局方法实现上面功能,如下代码:

 

 1 // EmoTabBarController.m - 版本4
 2 // Emo微博
 3 
 4 #import "EmoTabBarController.h"
 5 #import "UIImage+Image.h"
 6 
 7 @interface EmoTabBarController ()
 8 @end
 9 
10 @implementation EmoTabBarController
11 
12 // 什么时候调用:当第一次使用这个类或者子类的时候调用
13 // ”+ (void)initialize{}“作用:类的初始化,其实”+ (void)load{}“也是可以初始化类的
14 + (void)initialize
15 {
16     // 获取所有的tabBarItem外观标识,appearance只要一个类遵守UIAppearance,就能获取全局的外观,UIView
18     // 获取方法一:
19     // UITabBarItem *item = [UITabBarItem appearance];
20     //为什么不用方法一的原因是:所有文件中,只要是协议里的 tabBarItem 都会被修改
21 
22     // 方法二:
23     // self是指向EmoTabBarController
24     // 下面的代码意思是:仅仅获取当前这个类下面的所有tabBarItem,对其他文件中的 tabBarItem 无效。
25     UITabBarItem *item = [UITabBarItem appearanceWhenContainedIn:self, nil];
26     
27     NSMutableDictionary *att = [NSMutableDictionary dictionary];
28     att[NSForegroundColorAttributeName] = [UIColor orangeColor];
29     [item setTitleTextAttributes:att forState:UIControlStateSelected];
30 }
31 
32 - (void)viewDidLoad {
33     [super viewDidLoad];
34     // Do any additional setup after loading the view.
35     
36     // 添加所有子控制器
37     [self setUpAllChildViewController];
38 }
39 
40 // 如果通过模型设置控件的文字颜色,只能通过文本属性(富文本:颜色,字体,空心,阴影,图文混排)
41 // 在ios7之后,默认会把UITabBar上面的按钮图片渲染成蓝色
42 #pragma mark - 添加所有的子控制器
43 - (void)setUpAllChildViewController
44 {
45     // 首页
46     UIViewController *home = [[UIViewController alloc] init];
47     [self setUpOneChildViewController:home image:[UIImage imageNamed:@"tabbar_home"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_home_selected"] title:@"首页"];
48     home.view.backgroundColor = [UIColor greenColor];
49     
50     // 消息
51     UIViewController *message = [[UIViewController alloc] init];
52     [self setUpOneChildViewController:message image:[UIImage imageNamed:@"tabbar_message_center"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_message_center_selected"] title:@"消息"];
53     message.view.backgroundColor = [UIColor blueColor];
54     
55     // 发现
56     UIViewController *discover = [[UIViewController alloc] init];
57     [self setUpOneChildViewController:discover image:[UIImage imageNamed:@"tabbar_discover"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_discover_selected"] title:@"发现"];
58     discover.view.backgroundColor = [UIColor purpleColor];
59      
61     //
62     UIViewController *profile = [[UIViewController alloc] init];
63     [self setUpOneChildViewController:profile image:[UIImage imageNamed:@"tabbar_profile"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_profile_selected"] title:@""];
64     profile.view.backgroundColor = [UIColor lightGrayColor];
65 }
66 
67 #pragma mark - 添加一个子控制器
68 - (void)setUpOneChildViewController:(UIViewController *)vc image:(UIImage *)image selectedImage:(UIImage *)selectedImage title:(NSString *)title
69 {
70     vc.tabBarItem.title = title;
71     vc.tabBarItem.image = image;
72     //***此处被剪切到上面作为全局效果***//
73     vc.tabBarItem.badgeValue = @"10";
74     vc.tabBarItem.selectedImage = selectedImage;
75     [self addChildViewController:vc];
76 }
77 
79 @end

 

经过上述肆个案例之后,展示效果为:

 

     

 

实例伍:想要修改下面横栏按钮的位置,需要自定义一个 tabBar。新建一个UITabBar:

 

1 //  EmoTabBar.h - 版本1
2 //  Emo微博
3 
4 #import <UIKit/UIKit.h>
5 
6 @interface EmoTabBar : UITabBar
7 @end

 

 1 //  EmoTabBar.m - 版本1
 2 //  Emo微博
 3 
 4 #import "EmoTabBar.h"
 5 @interface EmoTabBar ()
//懒加载一个按钮,懒加载可以保证一个对象只有一个东西。
6 @property (nonatomic, weak) UIButton *plusButton; 7 @end 8 9 @implementation EmoTabBar 10 //重写 get 获取方法。 11 - (UIButton *)plusButton 12 {  //如果没有值才创建 13 if (_plusButton == nil) { 14 //如果没有值执行加载 button 15 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 16 [btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal]; 17 [btn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateHighlighted]; 18 [btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal]; 19 [btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted]; 20 21 // 默认按钮的尺寸跟背景图片一样大 22 // sizeToFit:默认会根据按钮的背景图片或者image和文字计算出按钮的最合适的尺寸 23 [btn sizeToFit]; 24 // 给按钮赋值 25 _plusButton = btn; 26 27 [self addSubview:_plusButton]; 28 29 } 30 return _plusButton; 31 } 32 33 // self.items.count UITabBarItem模型,有多少个子控制器就有多少个UITabBarItem模型 34 // 调系统自带的 tabBar子控件的位置 35 - (void)layoutSubviews 36 { 37 [super layoutSubviews]; 38 39 CGFloat w = self.bounds.size.width; 40 CGFloat h = self.bounds.size.height; 41 42 CGFloat btnX = 0; 43 CGFloat btnY = 0; 44 CGFloat btnW = self.bounds.size.width /(self.items.count + 1) = w / (self.items.count + 1);EmoTabBar的宽度/5“” 45 CGFloat btnH = self.bounds.size.height; 46 47 int i = 0; 48 // 调整系统自带的tabBar上的按钮位置
    // 遍历所有子控件。
49 for (UIView *tabBarButton in self.subviews) { 50 // 判断下是否是UITabBarButton,私有 API 用反射机制“NSClassFromString( )”根据一个字符串反射出一个类名" 51 if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton" )]) {
         // 在第二个的时候变为3,留出一个空格加按钮
52 if (i == 2) { 53 i = 3; 54 }
         // 有几个按钮
55 btnX = i * btnW; 56 57 tabBarButton.frame = CGRectMake(btnX, btnY, btnW, btnH); 58 59 i++;
         // NSLog(@"%@",tabBarButton); 打印出所有按钮的位置
60 } 61 } 63 64 // 设置添加按钮的位置,center 中心点的位置 65 self.plusButton.center = CGPointMake(w * 0.5, h * 0.5);
    // 默认按钮和图片一样大,换种操作改为23行
// self.plusButton.bounds = CGRectMake(0, 0, self.plusButton, currentBackgroundImage.size.width,self.plusButton, currentBackgroundImage.size.height);)
66 } 67 68 @end

 

  1 //  EmoTabBarController.m - 版本5
  2 //  Emo微博
  3 
  4 
  5 #import "EmoTabBarController.h"
  6 #import "UIImage+Image.h"
  7 #import "EmoTabBar.h"
  8 
  9 #import <objc/message.h>
 10 
 11 @interface EmoTabBarController ()
 12 @end
 13 
 14 @implementation EmoTabBarController
 15 
 16 // 什么调用:当第一次使用这个类或者子类的时候调用
 17 // 作用:初始化类
 18 // appearance只要一个类遵守UIAppearance,就能获取全局的外观,UIView
 19 + (void)initialize
 20 {
 21     // 获取所有的tabBarItem外观标识
 22 //    UITabBarItem *item = [UITabBarItem appearance];
 23     
 24     // self -> CZTabBarController
 25     // 获取当前这个类下面的所有tabBarItem
 26     UITabBarItem *item = [UITabBarItem appearanceWhenContainedIn:self, nil];
 27     
 28     NSMutableDictionary *att = [NSMutableDictionary dictionary];
 29     att[NSForegroundColorAttributeName] = [UIColor orangeColor];
 30     //    [att setObject:[UIColor orangeColor] forKey:NSForegroundColorAttributeName];
 31     
 32     [item setTitleTextAttributes:att forState:UIControlStateSelected];
 33 }
 34 
 35 - (void)viewDidLoad {
 36     [super viewDidLoad];
 37     // Do any additional setup after loading the view.
 38     // 添加所有子控制器
 39     [self setUpAllChildViewController];
 40     // 自定义tabBar
 41     EmoTabBar *tabBar = [[EmoTabBar alloc] initWithFrame:self.tabBar.frame];
 42     NSLog(@"%@",self.tabBar);
 43     // 利用KVC把readly的属性改
 44     [self setValue:tabBar forKeyPath:@"tabBar"];
 45     // objc_msgSend(self, @selector(setTabBar:),tabBar);//xcode 不希望用户使用消息机制
 46     NSLog(@"%@",self.tabBar);
 47     // self.tabBar = tabBar; //这句会报错,只读,换位用 KVC 看44行
 48     // 修改系统tabBar上面的按钮的位置
 49 //    NSLog(@"%@",self.tabBar.subviews);
 52 }
 53 
 54 - (void)viewWillAppear:(BOOL)animated
 55 {
 56     [super viewWillAppear:animated];
 57 
 58 }
 59 
 60 // 如果通过模型设置控件的文字颜色,只能通过文本属性(富文本:颜色,字体,空心,阴影,图文混排)
 61 
 62 // 在ios7之后,默认会把UITabBar上面的按钮图片渲染成蓝色
 63 #pragma mark - 添加所有的子控制器
 64 - (void)setUpAllChildViewController
 65 {
 66     // 首页
 67     UIViewController *home = [[UIViewController alloc] init];
 68     [self setUpOneChildViewController:home image:[UIImage imageNamed:@"tabbar_home"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_home_selected"] title:@"首页"];
 69     home.view.backgroundColor = [UIColor greenColor];
 70     
 71     // 消息
 72     UIViewController *message = [[UIViewController alloc] init];
 73     [self setUpOneChildViewController:message image:[UIImage imageNamed:@"tabbar_message_center"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_message_center_selected"] title:@"消息"];
 74     message.view.backgroundColor = [UIColor blueColor];
 75     
 76     // 发现
 77     UIViewController *discover = [[UIViewController alloc] init];
 78     [self setUpOneChildViewController:discover image:[UIImage imageNamed:@"tabbar_discover"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_discover_selected"] title:@"发现"];
 79     discover.view.backgroundColor = [UIColor purpleColor];
 80     
 81 
 82     //
 83     UIViewController *profile = [[UIViewController alloc] init];
 84     [self setUpOneChildViewController:profile image:[UIImage imageNamed:@"tabbar_profile"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_profile_selected"] title:@""];
 85     profile.view.backgroundColor = [UIColor lightGrayColor];
 86 }
 87 
 88 #pragma mark - 添加一个子控制器
 89 - (void)setUpOneChildViewController:(UIViewController *)vc image:(UIImage *)image selectedImage:(UIImage *)selectedImage title:(NSString *)title
 90 {
 91     vc.tabBarItem.title = title;
 92     vc.tabBarItem.image = image;
 93     vc.tabBarItem.badgeValue = @"10";
 94     vc.tabBarItem.selectedImage = selectedImage;
 95 
 96     [self addChildViewController:vc];
 97 }
 98 
 99 
100 @end

 

 

划分模块,新建文件夹:

Classes:

  Main(主框架):

    Controller:EmoTabBarController.h + EmoTabBarController.m

    Model:

    View:EmoTabBar.h + EmoTabBar.m

  Other(其他):

    AppDelegate.h + AppDelegate.m + main.m

    Category: UIImage+image.h + UIImage+image.m

  Home(首页):

    Controller、Model、View

  Discover(发现):

    Controller、Model、View

  Message(信息):

    Controller、Model、View

  Profile(我):

    Controller、Model、View

 

**** 整改过的所有代码,版本重新计数 ****

 

1 //  EmoTabBarController.h
2 //  Emo微博
3 //  Main - Controller
4 
5 #import <UIKit/UIKit.h>
6 @interface EmoTabBarController : UITabBarController
7 @end

 

  1 //  EmoTabBarController.m
  2 //  Emo微博
  3 //  Main - Controller
  4 
  5 #import "EmoTabBarController.h"
  6 #import "UIImage+Image.h"
  7 #import "EmoTabBar.h"
  8 #import "EmoHomeViewController.h"
  9 #import "EmoMessageViewController.h"
 10 #import "EmoDiscoverViewController.h"
 11 #import "EmoProfileViewController.h"
 12 #import "EmoNavigationController.h"
 13 
 14 @interface EmoTabBarController ()<EmoTabBarDelegate>
 15 @property (nonatomic, strong) NSMutableArray *items;
 16 @property (nonatomic, weak) EmoHomeViewController *home;
 17 @end
 18 
 19 @implementation EmoTabBarController
 20 - (NSMutableArray *)items
 21 {
 22 
 23     if (_items == nil) {
 24         _items = [NSMutableArray array];
 25         
 26     }
 27     return _items;
 28 }
 29 
 30 - (void)viewDidLoad {
 31     [super viewDidLoad];
 32     // Do any additional setup after loading the view.
 33     
 34     // 添加所有子控制器
 35     [self setUpAllChildViewController];
 36     
 37  
 38     // 自定义tabBar
 39     [self setUpTabBar];
 40     
 41 }
 42 
 43 #pragma mark - 设置tabBar
 44 - (void)setUpTabBar
 45 {
 46     // 自定义tabBar
 47     EmoTabBar *tabBar = [[EmoTabBar alloc] initWithFrame:self.tabBar.frame];
 48     tabBar.backgroundColor = [UIColor whiteColor];
 49     
 50     // 设置代理
 51     tabBar.delegate = self;
 52     
 53     // 给tabBar传递tabBarItem模型
 54     tabBar.items = self.items;
 55     
 56     // 添加自定义tabBar
 57     [self.view addSubview:tabBar];
 58     
 59     // 移除系统的tabBar
 60     [self.tabBar removeFromSuperview];
 61 }
 62 
 63 #pragma mark - 当点击tabBar上的按钮调用
 64 - (void)tabBar:(EmoTabBar *)tabBar didClickButton:(NSInteger)index
 65 {
 66     self.selectedIndex = index;
 67 }
 68 
 69 - (void)viewWillAppear:(BOOL)animated
 70 {
 71     [super viewWillAppear:animated];
 72     
 73 //    NSLog(@"%@",self.tabBar.items);
 74     
 75     
 76 }
 77 
 78 
 79 #pragma mark - 添加所有的子控制器
 80 - (void)setUpAllChildViewController
 81 {
 82     // 首页
 83     EmoHomeViewController *home = [[EmoHomeViewController alloc] init]; 
 84     [self setUpOneChildViewController:home image:[UIImage imageNamed:@"tabbar_home"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_home_selected"] title:@"首页"];
 85     _home = home;
 86     
 87     // 消息
 88     CZMessageViewController *message = [[CZMessageViewController alloc] init];
 89     [self setUpOneChildViewController:message image:[UIImage imageNamed:@"tabbar_message_center"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_message_center_selected"] title:@"消息"];
 90 
 91     
 92     // 发现
 93     CZDiscoverViewController *discover = [[CZDiscoverViewController alloc] init];
 94     [self setUpOneChildViewController:discover image:[UIImage imageNamed:@"tabbar_discover"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_discover_selected"] title:@"发现"];
 95 
 96     
 97     //
 98     CZProfileViewController *profile = [[CZProfileViewController alloc] init];
 99     [self setUpOneChildViewController:profile image:[UIImage imageNamed:@"tabbar_profile"] selectedImage:[UIImage imageWithOriginalName:@"tabbar_profile_selected"] title:@""];
100 
101 }
102 
103 // navigationItem决定导航条上的内容
104 // 导航条上的内容由栈顶控制器的navigationItem决定
105 #pragma mark - 添加一个子控制器
106 - (void)setUpOneChildViewController:(UIViewController *)vc image:(UIImage *)image selectedImage:(UIImage *)selectedImage title:(NSString *)title
107 {
108 //    // navigationItem模型
109 //    vc.navigationItem.title = title;
110 //    // 设置子控件对应tabBarItem的模型属性
111 //    vc.tabBarItem.title = title;
112     vc.title = title;
113     vc.tabBarItem.image = image;
114     vc.tabBarItem.selectedImage = selectedImage;
115     
116     // 保存tabBarItem模型到数组
117     [self.items addObject:vc.tabBarItem];
118     
119     EmoNavigationController *nav = [[EmoNavigationController alloc] initWithRootViewController:vc];
120 
121     [self addChildViewController:nav];
122 }
123 
124 
125 @end

 

1 //  EmoNavigationController.h
2 //  Emo微博
3 //  Main - Controller
4 
5 #import <UIKit/UIKit.h>
6 @interface EmoNavigationController : UINavigationController
7 @end

 

 1 //  EmoNavigationController.m
 2 //  Emo微博
 3 //  Main - Controller
 4 
 5 #import "EmoNavigationController.h"
 6 
 7 @interface EmoNavigationController ()
 8 @end
 9 
10 @implementation EmoNavigationController
11 
12 + (void)initialize
13 {
14     // 获取当前类下面的UIBarButtonItem
15     UIBarButtonItem *item = [UIBarButtonItem appearanceWhenContainedIn:self, nil];
16     
17     // 设置导航条按钮的文字颜色
18     NSMutableDictionary *titleAttr = [NSMutableDictionary dictionary];
19     titleAttr[NSForegroundColorAttributeName] = [UIColor orangeColor];
20     [item setTitleTextAttributes:titleAttr forState:UIControlStateNormal];
21     
22 }
23 
24 - (void)viewDidLoad {
25     [super viewDidLoad];
26     // Do any additional setup after loading the view.
27 }
28 
29 - (void)didReceiveMemoryWarning {
30     [super didReceiveMemoryWarning];
31     // Dispose of any resources that can be recreated.
32 }
33 
34 
35 @end

 

 1 //  EmoTabBar.h
 2 //  Emo微博
 3 //  Classes - Main - View
 4 
 5 #import <UIKit/UIKit.h>
 6 
 7 @class EmoTabBar;
 8 
 9 @protocol EmoTabBarDelegate <NSObject>
10 @optional
11 - (void)tabBar:(EmoTabBar *)tabBar didClickButton:(NSInteger)index;
12 @end
13 
14 @interface CZTabBar : UIView
15 //@property (nonatomic, assign) NSUInteger tabBarButtonCount;
16 // items:保存每一个按钮对应tabBarItem模型
17 @property (nonatomic, strong) NSArray *items;
18 @property (nonatomic, weak) id<EmoTabBarDelegate> delegate;
19 @end

 

  1 //  EmoTabBar.m
  2 //  Emo微博
  3 //  Classes - Main - View
  4 
  5 #import "EmoTabBar.h"
  6 #import "EmoTabBarButton.h"
  7 @interface EmoTabBar ()
  8 @property (nonatomic, weak) UIButton *plusButton;
  9 @property (nonatomic, strong) NSMutableArray *buttons;
 10 @property (nonatomic, weak) UIButton *selectedButton;
 11 @end
 12 
 13 @implementation EmoTabBar
 14 - (NSMutableArray *)buttons
 15 {
 16     if (_buttons == nil) {
 17         _buttons = [NSMutableArray array];
 18     }
 19     return _buttons;
 20 }
 21 
 22 //- (instancetype)initWithFrame:(CGRect)frame
 23 //{
 24 //    if (self = [super initWithFrame:frame]) {
 25 //        
 26 //        
 27 //    }
 28 //    
 29 //    return self;
 30 //}
 31 
 32 - (void)setItems:(NSArray *)items
 33 {
 34     _items = items;
 35     // 遍历模型数组,创建对应tabBarButton
 36     for (UITabBarItem *item in _items) {
 37         
 38         CZTabBarButton *btn = [CZTabBarButton buttonWithType:UIButtonTypeCustom];
 39         
 40         // 给按钮赋值模型,按钮的内容由模型对应决定
 41         btn.item = item;
 42         
 43         btn.tag = self.buttons.count;
 44         
 45         [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
 46         
 47         if (btn.tag == 0) { // 选中第0个
 48             [self btnClick:btn];
 49             
 50         }
 51    
 52         [self addSubview:btn];
 53         
 54         // 把按钮添加到按钮数组
 55         [self.buttons addObject:btn];
 56     }
 57 }
 58 
 59 // 点击tabBarButton调用
 60 -(void)btnClick:(UIButton *)button
 61 {
 62     _selectedButton.selected = NO;
 63     button.selected = YES;
 64     _selectedButton = button;
 65     
 66     // 通知tabBarVc切换控制器,
 67     if ([_delegate respondsToSelector:@selector(tabBar:didClickButton:)]) {
 68         [_delegate tabBar:self didClickButton:button.tag];
 69     }
 70 }
 71 
 72 
 73 - (UIButton *)plusButton
 74 {
 75     if (_plusButton == nil) {
 76         
 77         UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
 78         [btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
 79         [btn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateHighlighted];
 80         [btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
 81         [btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
 82         
 83         // 默认按钮的尺寸跟背景图片一样大
 84         // sizeToFit:默认会根据按钮的背景图片或者image和文字计算出按钮的最合适的尺寸
 85         [btn sizeToFit];
 86         
 87         _plusButton = btn;
 88         
 89         [self addSubview:_plusButton];
 90         
 91     }
 92     return _plusButton;
 93 }
 94 
 95 // self.items UITabBarItem模型,有多少个子控制器就有多少个UITabBarItem模型
 96 // 调整子控件的位置
 97 - (void)layoutSubviews
 98 {
 99     [super layoutSubviews];
100     
101     CGFloat w = self.bounds.size.width;
102     CGFloat h = self.bounds.size.height;
103     CGFloat btnX = 0;
104     CGFloat btnY = 0;
105     CGFloat btnW = w / (self.items.count + 1);
106     CGFloat btnH = self.bounds.size.height;
107 
108     int i = 0;
109     // 设置tabBarButton的frame
110     for (UIView *tabBarButton in self.buttons) {
111         if (i == 2) {
112             i = 3;
113         }
114         btnX = i * btnW;
115         tabBarButton.frame = CGRectMake(btnX, btnY, btnW, btnH);
116         i++;
117     }
118     
119     // 设置添加按钮的位置
120     self.plusButton.center = CGPointMake(w * 0.5, h * 0.5);
121     
122 }
123 
124 @end

 

1 //  EmoTabBarButton.h
2 //  Emo微博
3 //  Classes - Main - View
4 
5 #import <UIKit/UIKit.h>
6 @interface EmoTabBarButton : UIButton
7 @property (nonatomic, strong) UITabBarItem *item;
8 @end

 

 1 //  EmoTabBarButton.m
 2 //  Emo微博
 3 //  Classes - Main - View 
 4 
 5 #import "EmoTabBarButton.h"
 6 #import "EmoBadgeView.h"
 7 #define EmoImageRidio 0.7
 8 @interface EmoTabBarButton ()
 9 @property (nonatomic, weak) EmoBadgeView *badgeView;
10 @end
11 
12 @implementation EmoTabBarButton
13 
14 // 重写setHighlighted,取消高亮做的事情
15 - (void)setHighlighted:(BOOL)highlighted{}
16 // 懒加载badgeView
17 - (EmoBadgeView *)badgeView
18 {
19     if (_badgeView == nil) {
20         CZBadgeView *btn = [CZBadgeView buttonWithType:UIButtonTypeCustom];
21         [self addSubview:btn];
22         _badgeView = btn;
23     }
24     return _badgeView;
25 }
26 
27 - (instancetype)initWithFrame:(CGRect)frame
28 {
29     if (self = [super initWithFrame:frame]) {
30         // 设置字体颜色
31         [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
32         [self setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
33         // 图片居中
34         self.imageView.contentMode = UIViewContentModeCenter;
35         // 文字居中
36         self.titleLabel.textAlignment = NSTextAlignmentCenter;
37         // 设置文字字体
38         self.titleLabel.font = [UIFont systemFontOfSize:12];
39     }
40     return self;
41 }
42 // 传递UITabBarItem给tabBarButton,给tabBarButton内容赋值
43 - (void)setItem:(UITabBarItem *)item
44 {
45     _item = item;
46     [self observeValueForKeyPath:nil ofObject:nil change:nil context:nil];
47 
48     // KVO:时刻监听一个对象的属性有没有改变
49     // 给谁添加观察者
50     // Observer:按钮
51     [item addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
52     [item addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil];
53     [item addObserver:self forKeyPath:@"selectedImage" options:NSKeyValueObservingOptionNew context:nil];
54     [item addObserver:self forKeyPath:@"badgeValue" options:NSKeyValueObservingOptionNew context:nil];
55     
56 }
57 
58 // 只要监听的属性一有新值,就会调用
59 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
60 {
61     
62     [self setTitle:_item.title forState:UIControlStateNormal];
63     [self setImage:_item.image forState:UIControlStateNormal];
64     [self setImage:_item.selectedImage forState:UIControlStateSelected];
65     // 设置badgeValue
66     self.badgeView.badgeValue = _item.badgeValue;
67 }
68 
69 // 修改按钮内部子控件的frame
70 - (void)layoutSubviews
71 {
72     [super layoutSubviews];
73     
74     // 1.imageView
75     CGFloat imageX = 0;
76     CGFloat imageY = 0;
77     CGFloat imageW = self.bounds.size.width;
78     CGFloat imageH = self.bounds.size.height * CZImageRidio;
79     self.imageView.frame = CGRectMake(imageX, imageY, imageW, imageH);
80     
81     // 2.title
82     CGFloat titleX = 0;
83     CGFloat titleY = imageH - 3;
84     CGFloat titleW = self.bounds.size.width;
85     CGFloat titleH = self.bounds.size.height - titleY;
86     self.titleLabel.frame = CGRectMake(titleX, titleY, titleW, titleH);
87     
88     // 3.badgeView
89     self.badgeView.x = self.width - self.badgeView.width - 10;
90     self.badgeView.y = 0;
91 }
92 
93 @end

 

1 //  EmoBadgeView.h
2 //  Emo微博
3 //  Classes - Main - View
4 
5 #import <UIKit/UIKit.h>
6 @interface CZBadgeView : UIButton
7 @property (nonatomic, copy) NSString *badgeValue;
8 @end

 

 1 //  EmoBadgeView.m
 2 //  Emo微博
 3 //  Classes - Main - View
 4 
 5 #import "EmoBadgeView.h"
 6 #define EmoBadgeViewFont [UIFont systemFontOfSize:11]
 7 @implementation EmoBadgeView
 8 
 9 - (instancetype)initWithFrame:(CGRect)frame
10 {
11     if (self = [super initWithFrame:frame]) {
12         self.userInteractionEnabled = NO;
13         [self setBackgroundImage:[UIImage imageNamed:@"main_badge"] forState:UIControlStateNormal];
14         
15         // 设置字体大小
16         self.titleLabel.font = CZBadgeViewFont;
17         [self sizeToFit];
18     }
19     return self;
20 }
21 
22 - (void)setBadgeValue:(NSString *)badgeValue
23 {
24     _badgeValue = badgeValue;
25     
26     // 判断badgeValue是否有内容
27     if (badgeValue.length == 0 || [badgeValue isEqualToString:@"0"]) { // 没有内容或者空字符串,等于0
28         self.hidden = YES;
29     }else{
30         self.hidden = NO;
31     }
32     
33    CGSize size = [badgeValue sizeWithFont:CZBadgeViewFont];
34     NSLog(@"%f--%f",size.width,self.width);
35     if (size.width > self.width) { // 文字的尺寸大于控件的宽度
36         [self setImage:[UIImage imageNamed:@"new_dot"] forState:UIControlStateNormal];
37         [self setTitle:nil forState:UIControlStateNormal];
38         [self setBackgroundImage:nil forState:UIControlStateNormal];
39     }else{
40         [self setBackgroundImage:[UIImage imageNamed:@"main_badge"] forState:UIControlStateNormal];
41         [self setTitle:badgeValue forState:UIControlStateNormal];
42         [self setImage:nil forState:UIControlStateNormal];
43     }
44     
45 }
46 
47 @end

 

posted on 2015-11-20 01:41  Emo_Lin  阅读(145)  评论(0)    收藏  举报

导航