首先看一下最终效果:
一、底部TabBar和TabBarItem的封装
1. TabBarItem
该父类又派生出两个子类:TabBarItemCommon(中间加号按钮两边的四个按钮)和TabBarItemCompose(中间的加号按钮)
对于TabBarItemCommon,首先重写其initWithFrame方法,用于初始化时设置按钮中文字的位置、大小和按钮图片的内容模式等;
-(id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
// 设置文字居中
self.titleLabel.textAlignment = NSTextAlignmentCenter;
// 设置文字大小
self.titleLabel.font = [UIFont systemFontOfSize:kTitleSize];
// 设置图片的内容模式
self.imageView.contentMode = UIViewContentModeCenter;
}
return self;
}
然后,重写其setHighlighted方法,防止点击按钮时触发highlighted状态,并重写imageRectForContentRect和TitleRectForContentRect方法,调整按钮内部image和label的frame。
#pragma mark 覆盖父类在highlighted时的所有操作
-(void)setHighlighted:(BOOL)highlighted
{
}
#pragma mark 调整内部ImageView的frame
-(CGRect)imageRectForContentRect:(CGRect)contentRect
{
CGFloat imageX = 0;
CGFloat imageY = 0;
CGFloat imageWidth = contentRect.size.width;
CGFloat imageHeight = contentRect.size.height * ( 1- kTitleRatio );
return CGRectMake(imageX, imageY, imageWidth, imageHeight);
}
#pragma mark 调整内部UILabel的frame
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
CGFloat titleX = 0;
CGFloat titleHeight = contentRect.size.height * kTitleRatio;
CGFloat titleY = contentRect.size.height - titleHeight - 3;
CGFloat titleWidth = contentRect.size.width;
return CGRectMake(titleX, titleY, titleWidth, titleHeight);
}
2、TabBar
TabBar主要负责创建底部的TabBar并向其中添加按钮,该类中定义了一个TabBarDelegate协议:
@protocol TabBarDelegate <NSObject>
@optional
-(void)tabBar:(TabBar*)tabBar itemSelectedFrom:(int)from to:(int)to;
-(void)composeItemSelected;
@end
主界面控制器作为其代理,当TabBar监听到按钮的点击事件后,将消息传递给主界面控制器MainViewController,由主界面控制器切换相应的子控制器和视图。
MainViewController.m
#pragma mark TabBar的代理方法
-(void)tabBar:(TabBar *)tabBar itemSelectedFrom:(int)from to:(int)to
{
if (to < 0 || to >= self.childViewControllers.count) {
return;
}
// 1. 移除旧控制器的View
UIViewController *oldVC = self.childViewControllers[from];
[oldVC.view removeFromSuperview];
// 2. 取出即将显示的控制器
UIViewController *newVC = self.childViewControllers[to];
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height - kTabBarHeight;
newVC.view.frame = CGRectMake(0, 0, width, height);
// 3. 添加新控制器的View到MainController中
[self.view addSubview:newVC.view];
_selectedController = newVC;
}
二、主控制器MainViewController
MainViewController中按顺序添加了所有的子控制器,所有的子控制器都由作为一个导航控制器的根控制器,这些导航控制器都由同一个MainNavigationController创建并初始化,以控制应用中所有控制器的样式。
// 1. 首页控制器
HomeViewController *home = [[HomeViewController alloc]init];
MainNavigationController *nav_home = [[MainNavigationController alloc]initWithRootViewController:home];
nav_home.delegate = self;
[self addChildViewController:nav_home];
// 2. 消息控制器
MessageViewController *message = [[MessageViewController alloc]init];
MainNavigationController *nav_message = [[MainNavigationController alloc]initWithRootViewController:message];
nav_message.delegate = self;
[self addChildViewController:nav_message];
// 3. 搜索控制器
SearchViewController *search = [[SearchViewController alloc]init];
MainNavigationController *nav_search = [[MainNavigationController alloc]initWithRootViewController:search];
nav_search.delegate = self;
[self addChildViewController:nav_search];
// 4. 个人资料控制器
ProfileViewController *profile = [[ProfileViewController alloc]init];
MainNavigationController *nav_profile = [[MainNavigationController alloc]initWithRootViewController:profile];
nav_profile.delegate = self;
[self addChildViewController:nav_profile];
三、(转)CoreAnimation介绍
一、Core Animation简介
* Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。
* Core Animation可以用在Mac OS X和iOS平台。
* 乔帮主在2007年的WWDC大会上亲自为你演示Core Animation的强大:点击查看视频
* Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
* 要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。
二、Core Animation的使用步骤
1.使用它需要先添加QuartzCore.framework框架和引入主头文件<QuartzCore/QuartzCore.h>
2.初始化一个CAAnimation对象,并设置一些动画相关属性
3.通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中,这样就能开始执行动画了
4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画
三、CAAnimation
* 从前面的叙述可以看出,要想执行动画,就必须初始化一个CAAnimation对象。
* 其实,一般情况下,我们使用的比较多的是CAAnimation的子类,因此,先大致看看CAAnimation的继承结构:
黑线代表继承,黑色文字代表类名,白色文字代表属性。其中CAMediaTiming是一个协议(protocol)。
1.CAAnimation的常用属性
* CAAnimation是所有动画类的父类,但是它不能直接使用,应该使用它的子类
* 常见属性有:
1> duration:动画的持续时间
2> repeatCount:动画的重复次数
3> timingFunction:控制动画运行的节奏
- kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
- kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
- kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
- kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
4> delegate:动画代理,用来监听动画的执行过程
代理对象需要实现的方法有:(这几个方法被定义在某个分类中)
1 @interface NSObject (CAAnimationDelegate) 2 // 动画开始执行的时候触发这个方法 3 - (void)animationDidStart:(CAAnimation *)anim; 4 5 // 动画执行完毕的时候触发这个方法 6 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; 7 @end
* 上面介绍的所有属性都是属于CAAnimation的,因此,CAAnimation的所有子类都能使用它们。
2.其他
* CAPropertyAnimation也是不能直接使用的,也要使用它的子类
* 所以,能用的动画类只剩下4个:CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup
四、CAPropertyAnimation
* CAPropertyAnimation是CAAnimation的子类,但是不能直接使用,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation
* 它有个NSString类型的keyPath属性,你可以指定CALayer的某个属性名为keyPath,并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@"position"为keyPath,就会修改CALayer的position属性的值,以达到平移的动画效果
* 因此,初始化好CAPropertyAnimation的子类对象后,必须先设置keyPath,搞清楚要修改的是CALayer的哪个属性,执行的是怎样的动画
imageRectForContentRect