[iOS UI进阶 - 2.4] 彩票Demo v1.4 转盘动画
2015-01-17 01:04
861 查看
A.需求
幸运广场界面中有一个幸运转盘,平时能够自动缓缓转动
能够选择星座
点击“开始选号”开速旋转转盘,旋转一定周数
转盘转动速度节奏:开始-慢-块-慢-结束
设置其余的背景和按钮
code source:
彩票Demo https://github.com/hellovoidworld/HelloLottery
转盘Demo https://github.com/hellovoidworld/LuckyWheelDemo
B.实现
1.使用xib设计转盘
2.自定义类
(1)自定义一个继承UIVIew的类来控制这个转盘
(2)自定义一个继承UIButton的类来表示12星座按钮
3.给转盘添加12星座按钮
(1)先添加12个按钮重叠在12点方向
在awakeFromNib中添加子控件
(2)因为设置好了锚点,让12星座按钮旋转,平均排列在转盘上
(3)裁剪星座图片
星座图片原图
注意裁剪图片用的CG框架方法使用的单位是px像素,而UIImage用的是pt点(可以自动识别@2x),所以要根据屏幕分辨率来判别星座小图的裁剪大小。
(4)裁剪出来的图片太大了,在自定义星座按钮类中重新初始化按钮图片
4.让转盘转动起来
5.“开始选号”按钮
转盘加速旋转
6.放到彩票Demo中,添加上背景和按钮
注意:此画面取消了view扩展,所以view的大小就是中间可见部分,不含导航栏和状态栏。
幸运广场界面中有一个幸运转盘,平时能够自动缓缓转动
能够选择星座
点击“开始选号”开速旋转转盘,旋转一定周数
转盘转动速度节奏:开始-慢-块-慢-结束
设置其余的背景和按钮
code source:
彩票Demo https://github.com/hellovoidworld/HelloLottery
转盘Demo https://github.com/hellovoidworld/LuckyWheelDemo
B.实现
1.使用xib设计转盘
2.自定义类
(1)自定义一个继承UIVIew的类来控制这个转盘
(2)自定义一个继承UIButton的类来表示12星座按钮
3.给转盘添加12星座按钮
(1)先添加12个按钮重叠在12点方向
在awakeFromNib中添加子控件
- (void)awakeFromNib { // 由于按钮是要作为“转盘”控件的子控件,所以为了能够传递点击事件,要先开启“转盘”(UIImageView)的交互功能 self.luckyWheel.userInteractionEnabled = YES; // 添加12个星座按钮 for (int i=0; i<12; i++) { // 添加按钮 HVWLuckyWheelButton *button = [[HVWLuckyWheelButton alloc] init]; button.backgroundColor = [UIColor redColor]; // 设置按钮尺寸 button.bounds = CGRectMake(0, 0, 68, 143); // 设置按钮锚点,用于分布环形12个按钮 button.layer.anchorPoint = CGPointMake(0.5, 1); // 暂时把所有按钮都放在12点位置 button.layer.position = CGPointMake(self.center.x, self.center.y); [self.luckyWheel addSubview:button]; } }
(2)因为设置好了锚点,让12星座按钮旋转,平均排列在转盘上
// 环形分布12个星座按钮,围绕着锚点旋转 button.transform = CGAffineTransformMakeRotation(M_PI/6 * i);
(3)裁剪星座图片
星座图片原图
注意裁剪图片用的CG框架方法使用的单位是px像素,而UIImage用的是pt点(可以自动识别@2x),所以要根据屏幕分辨率来判别星座小图的裁剪大小。
- (void)awakeFromNib { // 由于按钮是要作为“转盘”控件的子控件,所以为了能够传递点击事件,要先开启“转盘”(UIImageView)的交互功能 self.luckyWheel.userInteractionEnabled = YES; // 添加12个星座按钮 for (int i=0; i<12; i++) { // 添加按钮 HVWLuckyWheelButton *button = [[HVWLuckyWheelButton alloc] init]; button.backgroundColor = [UIColor redColor]; // 设置按钮尺寸 button.bounds = CGRectMake(0, 0, 68, 143); // 设置按钮锚点,用于分布环形12个按钮 button.layer.anchorPoint = CGPointMake(0.5, 1); // 暂时把所有按钮都放在12点位置 button.layer.position = CGPointMake(self.center.x, self.center.y); // 取得星座图片总图 UIImage *sumImage = [UIImage imageNamed:@"LuckyAstrology"]; UIImage *sumImageSelected = [UIImage imageNamed:@"LuckyAstrologyPressed"]; // 使用CoreGraphic分割图片,得到独立的星座小图 // 这里图片的大小是提供给CGImageCreateWithImageInRect裁剪图片用的,所以要把单位从pt转换成px // 根据屏幕的分辨率来判别系统是否使用了@2x图片 CGFloat conImageWidth = sumImage.size.width / 12 * [UIScreen mainScreen].scale; CGFloat conImageHeight = sumImage.size.height * [UIScreen mainScreen].scale; CGFloat conImageX = i * conImageWidth; CGFloat conImageY = 0; // CGImage是用像素px来测量的,不是点pt,所以不能自动识别普通图片和@2x图片 UIImage *conImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(sumImage.CGImage, CGRectMake(conImageX, conImageY, conImageWidth, conImageHeight))]; UIImage *conImageSelected = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(sumImageSelected.CGImage, CGRectMake(conImageX, conImageY, conImageWidth, conImageHeight))]; // 设置按钮图片 [button setImage:conImage forState:UIControlStateNormal]; [button setImage:conImageSelected forState:UIControlStateSelected]; [button setBackgroundImage:[UIImage imageNamed:@"LuckyRototeSelected"] forState:UIControlStateSelected]; // 按钮点击事件 [button addTarget:self action:@selector(conButtonClicked:) forControlEvents:UIControlEventTouchDown]; // 环形分布12个星座按钮,围绕着锚点旋转 button.transform = CGAffineTransformMakeRotation(M_PI/6 * i); // 默认选中第一个按钮 if (0 == i) { [self conButtonClicked:button]; } [self.luckyWheel addSubview:button]; } } /** 星座按钮点击事件 */ - (void) conButtonClicked:(UIButton *) button { self.selectedLuckyWheelButton.selected = NO; button.selected = YES; self.selectedLuckyWheelButton = button; }
(4)裁剪出来的图片太大了,在自定义星座按钮类中重新初始化按钮图片
// // HVWLuckyWheelButton.m // LotteryLuckyWheel // // Created by hellovoidworld on 15/1/16. // Copyright (c) 2015年 hellovoidworld. All rights reserved. // #import "HVWLuckyWheelButton.h" @implementation HVWLuckyWheelButton /** 按钮前景图image的位置尺寸初始化 */ - (CGRect)imageRectForContentRect:(CGRect)contentRect { CGFloat width = 40; CGFloat height = 47; // 这里一定要用contentRect来取得按钮的尺寸,不能使用self.frame CGFloat x = (contentRect.size.width - width)/2; CGFloat y = 30; return CGRectMake(x, y, width, height); } /** 取消选中效果 */ - (void)setHighlighted:(BOOL)highlighted { // 置空 } @end
4.让转盘转动起来
/** 开始转盘旋转 */ - (void) startRotate { if (self.displayLink) return; // 创建循环刷新事件 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(luckyWheelRotate)]; self.displayLink = link; // 加入到主循环 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; } /** 转盘旋转实现方法 */ - (void) luckyWheelRotate { self.luckyWheel.transform = CGAffineTransformRotate(self.luckyWheel.transform, M_PI_4 / 100); } /** 停止转盘旋转 */ - (void) stopRotate { [self.displayLink invalidate]; self.displayLink = nil; }
5.“开始选号”按钮
转盘加速旋转
/** 开始选号 * 因为点击“开始选号”之后仅播放动画,不用设计交互操作,所以可以用CALayer动画来完成 */ - (IBAction)startChoose { // 禁止再次点击 self.startChooseButton.userInteractionEnabled = NO; // 先停止原来的轮盘转动 [self stopRotate]; // 停止轮盘的交互功能 self.luckyWheel.userInteractionEnabled = NO; CABasicAnimation *anim = [[CABasicAnimation alloc] init]; anim.keyPath = @"transform.rotation"; // 使用反余弦函数和矩阵换算计算出转盘现在的旋转角度 CGFloat wheelRoate = acosf(self.luckyWheel.transform.a); if (self.luckyWheel.transform.b < 0) { // 超出180°的情况 wheelRoate = M_PI * 2 - wheelRoate; } // 狂转3周,回到原来的位置 anim.toValue = @(wheelRoate + M_PI * 2 * 3); anim.duration = 2.0; // 设置代理 anim.delegate = self; //使用慢进慢出的动画节奏 anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [self.luckyWheel.layer addAnimation:anim forKey:nil]; } /** CALayer动画停止之后 */ - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { // 恢复轮盘的交互功能 self.luckyWheel.userInteractionEnabled = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 稍后恢复轮盘自动转动 [self startRotate]; // 恢复“开始选号”按钮点击 self.startChooseButton.userInteractionEnabled = YES; }); }
6.放到彩票Demo中,添加上背景和按钮
// // HVWLuckyViewController.m // HelloLottery // // Created by hellovoidworld on 15/1/16. // Copyright (c) 2015年 hellovoidworld. All rights reserved. // #import "HVWLuckyViewController.h" #import "HVWLuckyWheel.h" @interface HVWLuckyViewController () @end @implementation HVWLuckyViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self setEdgesForExtendedLayout:UIRectEdgeNone]; // 加载背景 // 由于是jpg格式,不能使用imageNamed在iameges.xcassets中寻找 NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"LuckyBackground" ofType:@"jpg"]; [self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:imagePath]]]; // 加载转盘 HVWLuckyWheel *luckyWheel = [HVWLuckyWheel hvwLuckyWheel]; luckyWheel.center = CGPointMake(self.view.frame.size.width/2, 220); [luckyWheel startRotate]; [self.view addSubview:luckyWheel]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end
注意:此画面取消了view扩展,所以view的大小就是中间可见部分,不含导航栏和状态栏。
相关文章推荐
- [iOS UI进阶 - 2.0] 彩票Demo v1.0
- [iOS UI进阶 - 2.1] 彩票Demo v1.1
- [iOS UI进阶 - 2.3] 彩票Demo v1.3
- [iOS UI进阶 - 2.2] 彩票Demo v1.2 UICollectionView基本
- iOS UI进阶-3.0 核心动画
- iOS开发 - 第02篇 - UI进阶 - 16 - 彩票(第三天)
- [iOS UI进阶 - 6.2] 核心动画CoreAnimation 练习代码
- ios开发-UI进阶-核心动画-时钟动画小案例
- iOS开发 - 第02篇 - UI进阶 - 14 - 彩票(第一天)
- [iOS UI进阶 - 4.0] 涂鸦app Demo
- [iOS UI进阶 - 5.0] 手势解锁Demo
- [iOS UI进阶 - 6.1] 核心动画CoreAnimation
- iOS开发 - 第02篇 - UI进阶 - 15 - 彩票(第二天)
- iOS开发 - 第02篇 - UI进阶 - 13 - 核心动画
- [iOS UI进阶 - 5.0] 手势解锁Demo
- [iOS UI进阶 - 6.3] UIView 动画
- IOS-DEMO4 scrapeAward/刮奖/脱衣服-进阶
- UI进阶--核心动画(Core Animation)
- UI基础-iOS黑马-UITableView6(A-Z#)- 多组汽车品牌demo
- UI进阶--iOS中的数据存储常用方式