一、UIView封装的动画
图层动画有2个致命的缺点:
1>默认情况下会反弹。
2>你所看到的动画都是假象,图层的属性一直都没有变过
所以建议能用UIView就用UIView,实在不行再用图层。
1.UIView的移动动画
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[UIView beginAnimations:nil context:nil];
//动画执行完毕后,会自动调用self的animateStop方法(用这种方式监听动画的执行
完毕)
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSecletor:@selector(animateStop)];
self.myView.center = CGPointMake(200,300);
[UIView commitAnimations];
}
2.UIView的转场动画
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[UIView transitionWithView:self.iconView duration:1.0 options:
UIViewAnimationOptionTransitionFlipFromTop animations:nil
completion:nil];
}
二、block动画
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[UIView animateWithDuration:1.0 animations:^{
self.myView.center = CGPointMake(200,300);
} completion:^(BOOL finished) {
//在这里监听动画的执行完毕
}];
}
三、实例:转盘
效果图
1.自定义一个View封装转盘。
2.创建一个xib用来描述转盘。(因为是固定的所以用xib)
3.提供一个类方法快速创建转盘。(在这个方法中加载xib)
+(instancetype)wheel
{
return [[[NSBundle mainBundle] loadNibNamed:@"MJWheel" owner:nil
options:nil] lastObject];
}
4.提供一个方法来设置旋转的动画效果
//开始不停地旋转
-(void)startRotating
{
if (self.link) return;
//1秒刷新60次
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self
selector:@selector(update)];
[link addToRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
}
-(void)update
{
self.centerWheel.transform = CGAffineTrasformRotate:
(self.centerWheel.transform,M_PI /500);
}
PS:因为用核心动画是假象,可能会造成以后点不准,并且进入后台后动画就会停止,
故不采取核心动画这种方式
5.来到控制器的viewDidLoad中,调用类方法创建转盘
{
[super viewDidLoad];
MJWheel *wheel = [MJWheel wheel];
wheel.center = CGPointMake(self.view.frame.width *
0.5,self.view.frame.height * 0.5);
[wheel startRotating];
[self.view addSubview:wheel];
}
6.来到MJWheel,重写awakeFromNib方法(在这个方法里添加按钮)
//在这个方法中取得属性才是有值的
-(void)awakeFromNib
{
//imageView默认不能与用户交互,所以先设置为YES
self.centerWheel.userInteractionEnabled = YES;
//加载大图片
UIImage *bigImage = [UIImage imageNamed:LuckyAstrology];
UIImage *bigImageSelected = [UIImage imageNamed:LuckyAstrologyP];
//从大图片中裁剪出对应星座的图片
CGFloat smallW = bigImage.size.width / 12 * [UIScreen mainScreen].scale;
CGFloat smallH = bigImage.size.height * [UIScreen mainScreen].scale;
for(int index = 0; index<12; index++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect smallRect = CGRectMake(index * smallW,0,smallW,smallH);
//CGImageCreateWithImageInRect:方法只认像素
CGImageRef smallImage = CGImageCreateWithImageInRect:
(bigImage.CGImage, smallRect);
CGImageRef smallImageSelected = CGImageCreateWithImageInRect:
(bigImageSelected.CGImage, smallRect);
[btn setImage:[UIImage imageWithCGImage:smallImage]
forState:UIControlStateNormal];
[btn setImage:[UIImage imageWithCGImage:smallImage]
forState:UIControlStateSelected];
[btn setBackgroundImage:[UIImage
imageNmaed:@"LuckyRototeSelected"] forState:UIControlSatateSelected];
btn.bounds = CGRectMake(0,0,68,143);
//设置锚点和位置
btn.layer.anchorPoint = CGPointMake(0.5,1);
btn.layer.position = CGPointMake(self.centerWheel.frame.size.width
*0.5,self.centerWheel.frame.size.height *0.5);
//设置旋转角度(绕着锚点进行旋转)
CGFloat angle = (30 * index) / 180.0 *M_PI;
btn.transform = CGAffineTransformMakeRotation(angle);
//监听按钮点击
[btn addTarget:self action:@selector(btnClick:)
forControlEvents:UIControlEventTouchDown];
[self.centerWheel addSubview:btn];
if (index == 0) {
[self btnClick:btn];
}
}
}
注意点:UIImage是按点来算的,CGImage是按像素来算的,后者是前者的2倍。
7.添加一个Button属性selectedBtn保存被选中的按钮
实现监听方法
-(void)btnClick:(UIButton *)btn
{
self.selectedBtn.selected = NO;
btn.selected = YES;
self.selectedBtn = btn;
}
8.调整按钮内部imageView的大小
1>自定义UIButton
2>重写imageRectForContextRect:方法
{
CGFloat imageW = 40;
CGFloat imageH = 47;
CGFloat imageX = (contentRect.size.width - imageW) * 0.5;
CGFloat imageY = 20;
return CGRectMake(imageX,imageY,imageW,imageH);
}
3>长按按钮不想让它变灰---重写setHighlighted:方法(什么都不用写)
9.开始选号
1>监听开始选号按钮并实现方法