iOS高级-QuartzCore框架-CoreAnimation和UIView动画的使用

一、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,调用类方法返回转盘

-(void)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);

//设置正常和选中状态下的Image

[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.添加一个属性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>监听开始选号按钮并实现方法

原文地址:https://www.cnblogs.com/marshall-yin/p/4782352.html