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
浙公网安备 33010602011771号