转盘
界面分析
- 点击开始,转盘开始转动
- 点击暂停,转盘停止转动
- 点击开始选号,转盘转动几下,指向正上方
- 转盘上的星座可以点击
- 动画过程中可以与用户进行交互,用UIView
素材分析
- 星座在一张图片上面
裁剪
- 放在一张图片上面的原因是:可以节省资源包的大小
- 必须要会裁剪
- 背景
封装一个View
- 背景和选号按钮位置固定不变
- xib
- 286*286 背景imageView
- 背景图片上面再添加一张图片
- 开始选号button
- 绑定类
- 封装,考虑外界怎么用?
- 提供一个类方法
- 从xib中加载,loadNibName:
- 重写initWithFrame:
- self = [NSBundle mainBundle]loadNibName:
- 提供一个类方法
添加按钮
控制器的view里设置开始、暂停按钮
监听按钮点击状态
-
把星座按钮添加到转盘上
- awakeFromNib
- 加载星座的大图片oriImage
- for循环
- 创建按钮
- 设置按钮的图片
- 设置背景图片,选中状态
- 设置按钮正常情况下展示的图片
- 图片、区域——>把指定区域裁剪出来
- CGImageCreateWithImageInRect:(图片,裁剪区域)
- oriImage.CGImage
- rect
- w:W /12
- h:H
- x:i*w
- y:0
- CGImageRef clipImage
- setImage:imageWithCGImage:forState:
- 问题: 看到的图片不是完整的,只能看到四分之一,像素是不会乘以坐标的,CGImageCreateWithImageInRect:是C语言方法,在C语言当中,使用的都是像素,6s加载的大图片是@2x,使用的是像素*2的,需要手动乘以2
- rect
- w:W /12 *【UIScreen mainScreen】.scale
- h:H *【UIScreen mainScreen】.scale
- x:i*w
- y:0
- rect
- 凡是C语言都有乘以scale
- 设置按钮选中状态下的图片
- oriSelImage
- CGImageCreateWithImageInRect:
- 设置按钮的尺寸大小
- 每个按钮相对上一个按钮旋转30度
- 先把按钮固定在0度的位置
- 设置按钮的大小 68 *143
- 锚点(0.5 ,1)
- position 转盘的中心点
- 设置按钮的背景颜色
- 对按钮做旋转形变操作
- button.transform
- 没有layer用CG,有layer用CA
- 带make
- angle +=30
- 角度转弧度
- angle*M_PI/180.0
- 按钮添加到contentImageView上面
- 监听按钮点击
- addTarget:action:
- 让点击的按钮成为选中状态,上一个取消选中
- 搞一个成员属性记录之前选中的按钮
- 取消上一个选中的按钮
- 让当前点击的按钮成为选中状态
- 让当前点击的按钮成为上一个选中按钮
- 让父控件响应事件
- 细节:
- 第一次进来,让第一个按钮默认成为选中状态
- 取消按钮的高亮状态
- 重写按钮内部的高亮方法
- 自定义按钮,取消按钮高亮状态
- setHighlighted:
画板(相似)
给外界提供一个接口
控制器里定义一个转盘view属性
-
到转盘里面去写开始、暂停的具体代码(属于内部的东西,写到内部去,给外界提供一个接口即可)
-
开始
- 不可以使用基础核心动画(不能与用户交互)
- 看到的是假象,选中的位置不准确,不能使用核心动画
- 使用UIView
- 定时器,NSTimer/CADisplayLink
CADisplayLink
- 把定时器加到主运行循环当中addRunLoop:
- 让转盘旋转contentImageView
- 不带make
- 旋转角度M_PI/300
- 用户可能重复点击开始,所以定时器需要懒加载,防止重复创建
- self.link.paused = NO;
- 不可以使用基础核心动画(不能与用户交互)
-
暂停
- self.link.paused = YES
-
调整星座按钮内部图片的大小
- 自定义按钮的方法里调整(三种方式)
返回按钮内部UIImageView的尺寸位置
- imageRectForContentRect:
- contentRect:是当前按钮的尺寸位置
- w:40固定死
- h:45
- y:20
- x:(父控件的宽度-按钮自己的宽度)*0.5
- `返回按钮内部UILabel的尺寸位置`
- titleRectForContentRect:
- `layoutSubviews`
中间开始选号
监听按钮点击
-
让转盘快速旋转几圈
- 不需要与用户交互
- keyPath
- toValue
- repeatCount = 1
- duration
- 动画加到背景图片上面的图片上
- contentImageView
- 不需要与用户交互
-
动画停止的时候,选中的按钮指向最上方
- 如何监听核心动画的暂停—— 代理,不用遵守协议(非正式协议)
- animationDidStop:当动画停止的时候调用
- 设置代理必须要在添加动画之前设置
- 当前点击的按钮preSelButton
- 父控件contentImageView,子控件:按钮
- 父控件倒着旋转回到最上方
- 获取选中按钮旋转的角度
- atan2(transform.b,transform.a)
- 让按钮的父控件倒着旋转回去
- 角度:- angle
解决星座按钮重叠的问题
- 让按钮的一部分能够点击
- hitTest:withEvent:
- 判断点在不在给定区域
- rect(指定高度:高度*0.5)
- CGRectContainsPoint(rect,point)
- 在:return [super hitTest:withEvent:]
- 不在:return nil
开始选号的时候暂停定时器
- self.link.paused = YES;