A.需求
  • 幸运广场界面中有一个幸运转盘,平时能够自动缓缓转动
  • 能够选择星座
  • 点击“开始选号”开速旋转转盘,旋转一定周数
  • 转盘转动速度节奏:开始-慢-块-慢-结束
  • 设置其余的背景和按钮
 
code source:
 
 
 
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=; i<; i++) { // 添加按钮
HVWLuckyWheelButton *button = [[HVWLuckyWheelButton alloc] init];
button.backgroundColor = [UIColor redColor]; // 设置按钮尺寸
button.bounds = CGRectMake(, , , );
// 设置按钮锚点,用于分布环形12个按钮
button.layer.anchorPoint = CGPointMake(0.5, );
// 暂时把所有按钮都放在12点位置
button.layer.position = CGPointMake(self.center.x, self.center.y); [self.luckyWheel addSubview:button];
}
}
 
 
(2)因为设置好了锚点,让12星座按钮旋转,平均排列在转盘上
         // 环形分布12个星座按钮,围绕着锚点旋转
button.transform = CGAffineTransformMakeRotation(M_PI/ * i);
 
 
(3)裁剪星座图片
星座图片原图
 
注意裁剪图片用的CG框架方法使用的单位是px像素,而UIImage用的是pt点(可以自动识别@2x),所以要根据屏幕分辨率来判别星座小图的裁剪大小。
 - (void)awakeFromNib {
// 由于按钮是要作为“转盘”控件的子控件,所以为了能够传递点击事件,要先开启“转盘”(UIImageView)的交互功能
self.luckyWheel.userInteractionEnabled = YES; // 添加12个星座按钮
for (int i=; i<; i++) { // 添加按钮
HVWLuckyWheelButton *button = [[HVWLuckyWheelButton alloc] init];
button.backgroundColor = [UIColor redColor]; // 设置按钮尺寸
button.bounds = CGRectMake(, , , );
// 设置按钮锚点,用于分布环形12个按钮
button.layer.anchorPoint = CGPointMake(0.5, );
// 暂时把所有按钮都放在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 / * [UIScreen mainScreen].scale;
CGFloat conImageHeight = sumImage.size.height * [UIScreen mainScreen].scale;
CGFloat conImageX = i * conImageWidth;
CGFloat conImageY = ; // 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/ * i); // 默认选中第一个按钮
if ( == 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 = ;
CGFloat height = ; // 这里一定要用contentRect来取得按钮的尺寸,不能使用self.frame
CGFloat x = (contentRect.size.width - width)/; CGFloat y = ;
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 / );
} /** 停止转盘旋转 */
- (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 < ) { // 超出180°的情况
wheelRoate = M_PI * - wheelRoate;
} // 狂转3周,回到原来的位置
anim.toValue = @(wheelRoate + M_PI * * );
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/, );
[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.4] 彩票Demo v1.4 转盘动画的更多相关文章

  1. [iOS UI进阶 - 2.0] 彩票Demo v1.0

    A.需求 1.模仿“网易彩票”做出有5个导航页面和相应功能的Demo 2.v1.0 版本搭建基本框架   code source:https://github.com/hellovoidworld/H ...

  2. [iOS UI进阶 - 2.1] 彩票Demo v1.1

    A.需求 1.优化项目设置 2.自定义导航栏标题按钮 3.多版本处理 4.iOS6和iOS7的适配 5.设置按钮背景 6.设置值UIBarButtonItem样式   code source: htt ...

  3. [iOS UI进阶 - 2.3] 彩票Demo v1.3

    A.需求 真机调试 "关于”模块 存储开关状态 打电话.发短信 应用评分 打开其他应用 cell 在iOS6 和 iOS7的适配 block的循环引用 屏幕适配 code source:   ...

  4. [iOS UI进阶 - 2.2] 彩票Demo v1.2 UICollectionView基本

    A.需要掌握的 设计.实现设置界面 cell的封装 UICollectionView的使用 自定义UICollectionView 抽取控制器父类 "帮助"功能 code sour ...

  5. [iOS UI进阶 - 5.0] 手势解锁Demo

    A.需求 1.九宫格手势解锁 2.使用了绘图和手势事件   code source: https://github.com/hellovoidworld/GestureUnlockDemo     B ...

  6. [iOS UI进阶 - 4.0] 涂鸦app Demo

    A.需求 1.超简易画图,只有一种画笔 2.清屏功能 3.回退功能 4.保存功能 5.使用了cocos2D   code source: https://github.com/hellovoidwor ...

  7. [iOS UI进阶 - 0] Quiartz2D

    A.简介 1. 需要掌握的 drawRect:方法的使用 常见图形的绘制:线条.多边形.圆 绘图状态的设置:文字颜色.线宽等 图形上下文状态的保存与恢复 图形上下文栈 1.基本图形绘制* 线段(线宽. ...

  8. iOS UI进阶-1.0 Quartz2D

    概述 Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统.Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF ...

  9. iOS开发——UI进阶篇(十七)CALayer,核心动画基本使用

    一.CALayer简介 1.CALayer在iOS中,文本输入框.一个图标等等,这些都是UIView你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个其实UIView之所以 ...

随机推荐

  1. error: dst ref refs/heads/zhCN_v0.13.1 receives from more than one src.

    http://segmentfault.com/q/1010000000257571 想要把本地的分支推送到远端 git push chucklu zhCN_v0.13.1 zhCN_v0.13.1 ...

  2. python写的第一个简单小游戏-猜数字

    #Filename:game1.py guess=10 running=True while running: try: answer=int(raw_input('Guess what i thin ...

  3. Eclipse中Python插件PyDev的安装与配置流程

    安装PyDev插件的两种安装方法: 方法1.下载地址:http://sourceforge.net/projects/pydev/files/,将下载的PyDev解压(目前最新版本 PyDev 4.5 ...

  4. 转:java提取图片中的像素

    本文转自:http://www.infosys.tuwien.ac.at/teaching/courses/WebEngineering/References/java/docs/api/java/a ...

  5. 模仿 "淘宝彩票" 的随机选球投注效果!

    我个人比较喜欢看网页的效果,前几天看了淘宝的“淘宝彩票”,今天仿造做了一个,我觉得比淘宝的体验要好. 查看 “淘宝彩票” 的网页源码发现,主要是用到了Css3 transform 的 Matrix 来 ...

  6. [反汇编练习] 160个CrackMe之004

    [反汇编练习] 160个CrackMe之004. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  7. Linux C enum

    /**************************************************************************** * Linux C enum * * 说明: ...

  8. apache开源项目 -- Wicket

    [infoq] Apache Wicket是一个功能强大.基于组件的轻量级Web应用框架,能将展现和业务逻辑很好地分离开来.你能用它创建易于测试.调试和支持的高质量Web 2.0应用.假设其他团队交付 ...

  9. 我的c语言经历

    作为一名计算机专业的学生,c语言是我的启蒙编程语言.当时,是刘慧老师带的课.很庆幸,是刘老师带的课.因为,后来当我这个人有了一些经历就会知道.对于像一张 白纸一样的大一新生.老师,如果能给学生很好的启 ...

  10. delphi 如何关闭 Unsafe typecast of 和 Unsafe type 的waring

    有时在Delphi使用指针类型的数据,总是提示如下: [Warning] FGroupFeedBack.pas(796): Unsafe typecast of 'Pointer' to 'TObje ...