1、UIView封裝的動畫
圖層動畫有2個致命的缺點:
1>默認狀況下會反彈。
2>你所看到的動畫都是假象,圖層的屬性一直都沒有變過
因此建議能用UIView就用UIView,實在不行再用圖層。
1.UIView的移動動畫oop
-(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]; }
2、block動畫spa
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [UIView animateWithDuration:1.0 animations:^{ self.myView.center = CGPointMake(200,300); } completion:^(BOOL finished) { //在這裏監聽動畫的執行完畢 }]; }
3、實例:轉盤
效果圖
code
1.自定義一個View封裝轉盤。
2.建立一個xib文件用來描述轉盤。(由於是固定的因此用xib)
3.提供一個類方法快速返回轉盤。(在這個方法中加載xib)orm
+(instancetype)wheel { return [[[NSBundle mainBundle] loadNibNamed:@"MJWheel" owner:nil options:nil] lastObject]; }
4.提供一個方法來設置旋轉的動畫效果blog
//開始不停地旋轉 -(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,調用類方法返回轉盤ip
-(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方法(在這個方法裏添加按鈕)get
//在這個方法中取得屬性纔是有值的 -(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來保存被選中的按鈕
實現監聽方法animation
-(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>監聽開始選號按鈕並實現方法