A.需求
1.模仿“网易彩票”做出有5个导航页面和相应功能的Demo
2.v1.0 版本搭建基本框架
code source:https://github.com/hellovoidworld/HelloLottery
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE4MDc1MzgyNTIxMzEucG5n.png?w=700&webp=1)
B.搭建基本框架
1.拖入TaBarController,5个NavigationController和对应的5个UIViewController
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkxODIzMTc5MTQucG5n.png?w=700&webp=1)
2.配置图标和启动画面
AppIcon直接拖入图片
LaunchImage在Xcode6中需要先更改启动图使用图库的图片,而不是LaunchImage.xib
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkyMDA1OTc4NTUucG5n.png?w=700&webp=1)
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkyMTc5NDI1MjcucG5n.png?w=700&webp=1)
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkyMzQ5Nzg3MzkucG5n.png?w=700&webp=1)
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkyNTUxMzU5MjIucG5n.png?w=700&webp=1)
2.引入图片包
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkyNzgyNTkyNTAucG5n.png?w=700&webp=1)
4. 按照模块分类代码包
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkyOTY1MzkxOTEucG5n.png?w=700&webp=1)
3.底部导航--自定义TabBar
(1)基本设计
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkzMTQ4MTkxMzIucG5n.png?w=700&webp=1)
a.自定义HVWTabBarController、继承自UIView的HVWTabBar、继承UIButton的HVWTabBarButton
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkzNDI0NzkzODgucG5n.png?w=700&webp=1)
b.在自定义TabBar控制器viewDidLoad,删除原来的TabBar,加上自定义的TabBar
c.加入自定义的按钮图片、选中图片
d.选中事件,转换图片
e.按下马上激发按钮激发
重写TabBarButton的[button setHighlighted:]取消高亮状态
HVWTabBarButton:
// 覆盖setHighlighted,取消点击时的高亮状态
- (void)setHighlighted:(BOOL)highlighted {
// [super setHighlighted:highlighted];
}
初步实现都在HVWTabBarController的viewDidLoad方法中:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. // 1.删除原来的TabBar
[self.tabBar removeFromSuperview]; // 2.添加自定义TabBar
HVWTabBar *hvwTabBar = [[HVWTabBar alloc] init];
hvwTabBar.frame = self.tabBar.frame;
hvwTabBar.backgroundColor = [UIColor greenColor]; // 设置绿色底的tabBar,稍后会被按钮图片覆盖
[self.view addSubview:hvwTabBar]; // 3.添加按钮
for (int i=; i<; i++) {
// 3.1创建按钮
HVWTabBarButton *button = [HVWTabBarButton buttonWithType:UIButtonTypeCustom];
button.tag = i; // 3.2设置按钮背景图片
[button setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"TabBar%d", i+]] forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"TabBar%dSel", i+]] forState:UIControlStateSelected]; // 3.3设置frame
CGFloat buttonWidth = hvwTabBar.frame.size.width / ;
CGFloat buttonHeight = hvwTabBar.frame.size.height;
CGFloat buttonX = i * buttonWidth;
CGFloat buttonY = ;
button.frame = CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight); // 3.4添加到tabBar
[hvwTabBar addSubview:button]; // 3.5添加监听事件
[button addTarget:self action:@selector(tabBarButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; // 3.6默认已经点击了第一个按钮
if (i == ) {
[self tabBarButtonClicked:button];
}
}
} - (void) tabBarButtonClicked:(HVWTabBarButton *) button {
// 1.取消选中之前的按钮
self.selectedButton.selected = NO; // 2.选中新点击的按钮
button.selected = YES; // 3.设置为当前选中的按钮
self.selectedButton = button; // 4.切换子控制器
self.selectedIndex = button.tag;
}
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkzNjE1MzcwNzIucG5n.png?w=700&webp=1)
(2)封装TabBar代码
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkzODA1OTQ3NTYucG5n.png?w=700&webp=1)
a.重写initWithFrame:创建初始化TabBar
b.移动子控件的初始化代码到layoutSubviews
c.通过代理转换Navigation页面
d.封装添加按钮函数
//
// HWTabBarController.m
// HelloLottery
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import "HvWTabBarController.h"
#import "HVWTabBar.h"
#import "HVWTabBarButton.h" @interface HVWTabBarController () <HVWTabBarDelegate> @end @implementation HVWTabBarController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. // 1.删除原来的TabBar
[self.tabBar removeFromSuperview]; // 2.添加自定义TabBar
HVWTabBar *hvwTabBar = [[HVWTabBar alloc] init];
hvwTabBar.frame = self.tabBar.frame;
hvwTabBar.backgroundColor = [UIColor greenColor]; // 设置绿色底的tabBar,稍后会被按钮图片覆盖
hvwTabBar.delegate = self;
[self.view addSubview:hvwTabBar];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark - HVWTabBarDelegate 代理方法
- (void)hvwTabBar:(HVWTabBar *)hvwTabBar didClickedButtonFrom:(int)from to:(int)to {
// 切换子控制器
self.selectedIndex = to;
} @end
//
// HVWTabBar.h
// HelloLottery
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import <UIKit/UIKit.h> @class HVWTabBar; /** 代理协议 */
@protocol HVWTabBarDelegate <NSObject>
@optional
- (void) hvwTabBar:(HVWTabBar *) hvwTabBar didClickedButtonFrom:(int) from to:(int) to;
@end @interface HVWTabBar : UIView /** 代理 */
@property(nonatomic, weak) id<HVWTabBarDelegate> delegate; @end
//
// HVWTabBar.m
// HelloLottery
//
// Created by hellovoidworld on 14/12/31.
// Copyright (c) 2014年 hellovoidworld. All rights reserved.
// #import "HVWTabBar.h"
#import "HVWTabBarButton.h" #define HVWTabBarButtonCount 5 @interface HVWTabBar() @property(nonatomic, weak) HVWTabBarButton *selectedButton; @end @implementation HVWTabBar // 重写initWithFrame方法,添加tabBar按钮
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self initButtons];
} return self;
} /** 初始化按钮 */
- (void) initButtons {
for (int i=; i<HVWTabBarButtonCount; i++) {
// 3.1创建按钮
HVWTabBarButton *button = [HVWTabBarButton buttonWithType:UIButtonTypeCustom];
button.tag = i; // 3.2设置按钮背景图片
[button setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"TabBar%d", i+]] forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"TabBar%dSel", i+]] forState:UIControlStateSelected]; // 3.3添加到tabBar
[self addSubview:button]; // 3.4添加监听事件
[button addTarget:self action:@selector(tabBarButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; // 3.5默认已经点击了第一个按钮
if (i == ) {
[self tabBarButtonClicked:button];
}
}
} /** 初始化子控件的位置尺寸 */
- (void)layoutSubviews {
[super layoutSubviews]; for (int i=; i<HVWTabBarButtonCount; i++) {
HVWTabBarButton *button = self.subviews[i];
CGFloat buttonWidth = self.frame.size.width / ;
CGFloat buttonHeight = self.frame.size.height;
CGFloat buttonX = i * buttonWidth;
CGFloat buttonY = ;
button.frame = CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight);
}
} - (void) tabBarButtonClicked:(HVWTabBarButton *) button {
// 1.调用代理方法,通知TabBarController切换子控制器
if ([self.delegate respondsToSelector:@selector(hvwTabBar:didClickedButtonFrom:to:)]) {
[self.delegate hvwTabBar:self didClickedButtonFrom:self.selectedButton.tag to:button.tag];
} // 2.取消选中之前的按钮
self.selectedButton.selected = NO; // 3.选中新点击的按钮
button.selected = YES; // 4.设置为当前选中的按钮
self.selectedButton = button;
} @end
4.头部Navigation导航栏主题设置
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTkzOTk1MDM5MTMucG5n.png?w=700&webp=1)
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTk0MTY1MzExMjYucG5n.png?w=700&webp=1)
(1)让applicatoin管理状态栏
(2)Navigation导航栏背景图片
(3)统一设置所有Navigation导航栏
[UINavigationBar appearance]; // 所有Navigation导航栏(头部导航栏)
(4)设置所有Navigation导航栏字体颜色
(5)根据系统版本,设置Navigation导航栏背景图片
(6)在二级页面隐藏底部导航条,重写导航控制器的push方法
a.自定义一个导航控制器HVWNavigationController类,重写push,隐藏底部导航栏
b.设置为每个NavigationController的class
c.导航控制器类的initialize只会在类第一次使用的时候调用一次
所以,导航栏的主题设置可以放在initialize方法中
解决:
(1)使用application管理状态栏
设置不使用控制器控制状态栏
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTk0MzYwNjM3OTUucG5n.png?w=700&webp=1)
在AppDelegate中设置:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch. // 设置状态栏样式为白色
application.statusBarStyle = UIStatusBarStyleLightContent; return YES;
}
(2)创建自定义NavigationController类,并设置5个Navigation控制器的class为此类
![[iOS UI进阶 - 2.0] 彩票Demo v1.0 [iOS UI进阶 - 2.0] 彩票Demo v1.0](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNjQ4NDczLzIwMTUwMS8wMTE3NTk0NTM1NjU5OTQucG5n.png?w=700&webp=1)
(3)不要删除原来的tabBar,而是覆盖它,才能控制push事件中底部导航栏
HVWTabBarController:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. // 1.添加自定义TabBar
HVWTabBar *hvwTabBar = [[HVWTabBar alloc] init];
hvwTabBar.frame = self.tabBar.bounds;
hvwTabBar.delegate = self; // 2.设置tabBar
[self.tabBar addSubview:hvwTabBar];
}
(4)在NavigationController中编写类初始化方法和重写push方法
//
// HVWNavigationController.m
// HelloLottery
//
// Created by hellovoidworld on 15/1/1.
// Copyright (c) 2015年 hellovoidworld. All rights reserved.
// #import "HVWNavigationController.h" @interface HVWNavigationController () @end @implementation HVWNavigationController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view. } - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} /** 类初始化方法,仅调用一次 */
+ (void) initialize {
// 获取能够控制所有NavigationBar的实例
UINavigationBar *navBar = [UINavigationBar appearance]; // 设置背景图片
NSString *bgImageName;
if (iOS7) { // 在HelloLottery-Prefix.pch中定义了判断iOS版本的全局变量
bgImageName = @"NavBar64";
} else {
bgImageName = @"NavBar";
} [navBar setBackgroundImage:[UIImage imageNamed:bgImageName] forBarMetrics:UIBarMetricsDefault]; // 设置文本
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
attr[NSForegroundColorAttributeName] = [UIColor whiteColor];
attr[NSFontAttributeName] = [UIFont systemFontOfSize:];
[navBar setTitleTextAttributes:attr];
} // 拦截所有的push操作
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
viewController.hidesBottomBarWhenPushed = YES; // 这是原来NavigationController中的tabBar,所以要设置自定义的tabBar为Navigation中的tabBar
[super pushViewController:viewController animated:YES];
} @end