转盘

转盘

界面分析

  • 点击开始,转盘开始转动
  • 点击暂停,转盘停止转动
  • 点击开始选号,转盘转动几下,指向正上方
  • 转盘上的星座可以点击
  • 动画过程中可以与用户进行交互,用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
          • 凡是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;

你可能感兴趣的:(转盘)