【转】iOS25彩票 幸运转盘

原文 : http://www.it165.net/pro/html/201409/21216.html

最终效果图:

各个view的关系图:

背景圆盘(需穴ky"http://www.it165.net/qq/" target="_blank"
class="keylink">qq/2828tKbA7SlMdWNreUJhc2VCYWNrZ3JvdW5kLnBuZzwvc3Ryb25nPjwvcD4KPHA+PGltZyBzcmM9"http://www.it165.net/uploadfile/files/2014/0901/20140901192959329.png"
alt="\">

盖在背景圆盘上面的转盘 LuckyRotateWheel.png


代表一个星座或生肖的按钮背景图片

穴ky"http://www.it165.net/qq/" target="_blank"
class="keylink">qq0tL2oMTK49iyyotLU1+7Pwre91tC1486qw6q147340NDQ/deqPC9zdHJvbmc+PC9wPgo8cD48c3Ryb25nPjxpbWcgc3JjPQ=="http://www.it165.net/uploadfile/files/2014/0901/20140901193000331.png"
alt="\">

对背景圆盘进行扣图,并在其上面盖上转盘图片的核心代码


在自定义的背景view中,画好了背景圆盘和背景转盘之后,

一次性添加12个代表星座或生肖的按钮,并设置旋转角度


一张集合了所有的代表星座的按钮的背景图片的大图片


一张集合了所有的代表星座的按钮的背景图片的大图片


需要根据不同的按钮的i值,

利用CGImageCreateWithImageInRect方法

从大图片中裁剪出一张小图片作为按钮的背景图片


供控制器调用,让圆转盘(circleBgView)慢悠悠地转


当用户点击圆转盘中心的【开始选号】按钮时,

让circleBgView所在图层,利用核心动画CA,

进行假的疯狂地快速旋转,并且动画完成时,

才让cirleBgView的transform真正地旋转负的一定角度,

让被点击的按钮指向正上方


控制器

view sourceprint?

01.<strong>//

02.//  LuckyNumController.h

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-27.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//

08.

09.#import <UIKit/UIKit.h>

10.

11.@interface LuckyNumController : UIViewController

12.

13.@end

14.</strong>


view sourceprint?

01.//

02.//  LuckyNumController.m

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-27.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//

08.

09.#import "LuckyNumController.h"

10.// 两个封装的view

11.// 顶部的三个按钮作为一整体添加到控制器的view

12.#import "TopThreeBtnsAsOne.h"

13.// 中间的所有东东,作为一个整体添加到控制器的view

14.#import "CircleView.h"

15.#import "CircleViewDelegate.h"

16.

17.@interface LuckyNumController ()<CircleViewDelegate>

18.{

19.TopThreeBtnsAsOne *_threeButton;

20.CircleView *_circle;

21.}

22.@end

23.

24.@implementation LuckyNumController

25.#pragma mark - 生命周期方法

26.// 控制器的view消失的时候,可以暂停转盘

27.- (void)viewDidDisappear:(BOOL)animated

28.{

29.[super viewDidDisappear:animated];

30.

31.[_circle pauseRotate];

32.}

33.// 控制器的view出现的时候,才需慢慢转动转盘

34.- (void)viewWillAppear:(BOOL)animated

35.{

36.[super viewWillAppear:animated];

37.

38.[_circle startSlowlyRotate];

39.}

40.

41.- (void)viewDidLoad

42.{

43.[super viewDidLoad];

44.

45.// 1.根据4inch或3.5   添加一个全屏的背景

46.[self setupFullScreenBg];

47.

48.// 2.添加顶部3个选择按钮作为一个整体

49.[self setupTopThreeBtnsAsOne];

50.

51.// 3.添加圆转盘整体

52.[self setupCircleView];

53.}

54.// 1.根据4inch或3.5   添加一个全屏的背景

55.- (void)setupFullScreenBg

56.{

57.UIImageView *bg = [[UIImageView alloc] initWithFrame:self.view.bounds];

58.bg.image = [UIImage imageNamed:[email protected]"[email protected]":@"[email protected]"];

59.bg.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

60.[self.view addSubview:bg];

61.}

62.// 2.添加顶部3个选择按钮作为一个整体

63.- (void)setupTopThreeBtnsAsOne

64.{

65.TopThreeBtnsAsOne *tb = [TopThreeBtnsAsOne threeBtnsAsOne];

66.CGFloat cx = self.view.frame.size.width * 0.5;

67.CGFloat cy = tb.frame.size.height * 0.5 + 20;

68.tb.center = CGPointMake(cx, cy);

69.[self.view addSubview:tb];

70._threeButton = tb;

71.}

72.// 3.添加圆转盘整体

73.- (void)setupCircleView

74.{

75.CircleView *circle = [CircleView circleView];

76.// 设置代理,监听其内部的 12星座或生肖按钮的点击状态

77.circle.delegate = self;

78.// 设置转盘为星座类型 或生肖类型

79.circle.circleType = CircleViewTypeAstrology;

80.circle.circleType = CircleViewTypeAnimal;

81.// 置于顶部的三个按钮的下方

82.CGFloat cx = _threeButton.center.x;

83.CGFloat cy = CGRectGetMaxY(_threeButton.frame) + circle.frame.size.height * 0.5;

84.// 对3.5inch作一个调整

85.if (!is4inch) {

86.// 3.5inch屏幕,往上移动20个点

87.cy -= 20;

88.}

89.circle.center = CGPointMake(cx, cy);

90.[self.view addSubview:circle];

91._circle = circle;

92.}

93.

94.#pragma mark - 转盘的代理方法 略

95.@end

幸运选号顶部的三个按钮,可作为一整体添加到LuckyNumController控制器中

view sourceprint?

01.//

02.//  TopThreeBtnsAsOne.h

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-30.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  幸运选号顶部的 三个按钮,可作为一整体添加到LuckyNumController控制器中

08.

09.#import <UIKit/UIKit.h>

10.

11.@interface TopThreeBtnsAsOne : UIView

12.

13.//  类方法返回 从xib创建的对象

14.+ (instancetype)threeBtnsAsOne;

15.@end

view sourceprint?

01.//

02.//  TopThreeBtnsAsOne.m

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-30.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  幸运选号顶部的 三个按钮,可作为一整体添加到LuckyNumController控制器中

08.

09.#import "TopThreeBtnsAsOne.h"

10.

11.@interface TopThreeBtnsAsOne()

12.

13.@end

14.

15.@implementation TopThreeBtnsAsOne

16.

17.//  类方法返回 从xib创建的对象

18.+ (instancetype)threeBtnsAsOne

19.{

20.return [[NSBundle mainBundle] loadNibNamed:@"TopThreeBtnsAsOne" owner:nil options:nil][0];

21.}

22.

23.@end


幸运转盘CircleView,是中部最大的view,

它包括由两个部组成,

分别是一个开始按钮、一个背景层CircleBgView,

其中背景层CircleBgView又包括三层,

分别是图片1圆盘(要扣图),图片2转盘,12个按钮

view sourceprint?

01.//

02.//  CircleView.h

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-30.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  幸运转盘CircleView,是中部最大的view,它包括由两个部组成,分别是一个开始按钮、一个背景层CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1圆盘(要扣图),图片2转盘,12个按钮

08.

09.#import <UIKit/UIKit.h>

10.@protocol CircleViewDelegate;

11.

12.// 让控制器可以选择幸运转盘的类型,选择星座 还是生肖,从而其内部会从不同的图片中裁剪一个个小按钮的背景图

13.typedef enum {

14.CircleViewTypeAstrology, // 星座

15.CircleViewTypeAnimal // 生肖

16.} CircleViewType;

17.

18.@interface CircleView : UIView

19.

20.// 类方法,返回实例对象

21.+ (instancetype)circleView;

22.// 让控制器可以选择幸运转盘的类型,选择星座 还是生肖,从而其内部会从不同的图片中裁剪一个个小按钮的背景图

23.@property (nonatomic, assign) CircleViewType circleType;

24.// 成员:代理,告诉控制器,内部点击的按钮的切换

25.@property (nonatomic, weak) id<CircleViewDelegate> delegate;

26.

27.// 开始慢悠悠地转动圆盘

28.- (void)startSlowlyRotate;

29.// 暂停计时器

30.- (void)pauseRotate;

31.// 停止圆盘的转动,并且清空计时器

32.- (void)stopRotate;

33.@end

view sourceprint?

001.//

002.//  CircleView.m

003.//  25_彩票

004.//

005.//  Created by beyond on 14-8-30.

006.//  Copyright (c) 2014年 com.beyond. All rights reserved.

007.//  幸运转盘CircleView,是中部最大的view,它包括由两个部组成,分别是一个开始按钮、一个背景层CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1圆盘(要扣图),图片2转盘,12个按钮

008.

009.#import "CircleView.h"

010.// 背景层CircleBgView 又包括三层,分别是图片1圆盘(要扣图),图片2转盘,12个按钮

011.#import "CircleBgView.h"

012.// 代表一个个星座按钮

013.#import "CircleItem.h"

014.#import "CircleViewDelegate.h"

015.

016.// 速度 : 1秒种转多少度

017.#define ILCircleRotateSpeedPerSecond (M_PI_4/2)

018.// 从transform用公式 算出角度

019.#define ILTransform2Angle(transform) atan2(transform.b, transform.a)

020.

021.

022.@interface CircleView ()

023.{

024.// 背景层CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1圆盘(要扣图),图片2转盘,12个按钮

025.CircleBgView *_circleBgView;

026.CADisplayLink *_timer;

027.}

028.@end

029.

030.@implementation CircleView

031.#pragma mark - 生命周期方法

032.+ (instancetype)circleView

033.{

034.return [[self alloc] init];

035.}

036.// 供外部调用,设置【Circle背景View 】上的12个按钮是星座图,还是生肖

037.- (void)setCircleType:(CircleViewType)circleType

038.{

039._circleType = circleType;

040.

041.// 更换【Circle背景View 】内部要使用的大图片

042.if (circleType ==CircleViewTypeAstrology) {

043.[_circleBgView set12BtnsBgWithBigImg:@"LuckyAstrology" selected:@"LuckyAstrologyPressed"];

044.} else {

045.[_circleBgView set12BtnsBgWithBigImg:@"LuckyAnimal" selected:@"LuckyAnimalPressed"];

046.}

047.}

048.// 初始化内部的子控件:1.开始按钮,2.Circle背景View (圆盘,转盘,12个星座或生肖按钮)

049.- (id)initWithFrame:(CGRect)frame

050.{

051.self = [super initWithFrame:frame];

052.if (self) {

053.//        self.backgroundColor = [UIColor yellowColor];

054.// 1.添加背景层CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1圆盘(要扣图),图片2转盘,12个按钮

055.[self setupCircleBgView];

056.

057.// 2.添加浮在圆转盘上面的 开始按钮

058.[self setupStartBtn];

059.}

060.return self;

061.}

062.// 1.添加背景层CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1圆盘(要扣图),图片2转盘,12个按钮

063.- (void)setupCircleBgView

064.{

065.// 内部固定了宽高

066.CircleBgView *bgView = [CircleBgView circleBgView];

067.[self addSubview:bgView];

068._circleBgView = bgView;

069.}

070.// 2.添加浮在圆转盘上面的 开始按钮

071.- (void)setupStartBtn

072.{

073.UIButton *startBtn = [UIButton buttonWithType:UIButtonTypeCustom];

074.// 开始按钮,位于圆转盘的中心

075.startBtn.bounds = CGRectMake(0, 0, 81, 81);

076.startBtn.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);

077.// 设置按钮图片

078.[startBtn setBtnBgImgForNormal:@"LuckyCenterButton" highlightedName:@"LuckyCenterButtonPressed"];

079.// 添加监听事件,开始转动转盘

080.[startBtn addTarget:self action:@selector(startBtnClicked) forControlEvents:UIControlEventTouchUpInside];

081.

082.[self addSubview:startBtn];

083.}

084.

085.

086.#pragma mark - 父类方法

087.// setFrame:和setBounds:能保证尺寸永远是286x286

088.- (void)setFrame:(CGRect)frame

089.{

090.frame.size = CGSizeMake(ILCircleWH, ILCircleWH);

091.[super setFrame:frame];

092.}

093.

094.- (void)setBounds:(CGRect)bounds

095.{

096.bounds.size = CGSizeMake(ILCircleWH, ILCircleWH);

097.[super setBounds:bounds];

098.}

099.

100.#pragma mark - 私有方法

101.// 监听【开始按钮】的点击事件,利用CA核心动画,进行假的快速旋转

102.- (void)startBtnClicked

103.{

104.// 0.先清空计时器

105.[self stopRotate];

106.

107.// 1.停止交互

108.self.userInteractionEnabled = NO;

109.

110.// 2.利用CA核心动画,进行假的 快速狂转

111.[self crazyRotate];

112.

113.// 通知代理

114.if ([_delegate respondsToSelector:@selector(circleView:willRoateToIndex:)]) {

115.[_delegate circleView:self willRoateToIndex:_circleBgView.selectedBtn.tag];

116.}

117.}

118.// 2.利用CA核心动画进行假的 狂转

119.- (void)crazyRotate

120.{

121.// 固定写法

122.CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];

123.// 从transform用公式 算出角度

124.// #define ILTransform2Angle(transform) atan2(transform.b, transform.a)

125.// 算出被点击的按钮的初始角度

126.CGFloat btnInitialAngle = ILTransform2Angle(_circleBgView.selectedBtn.transform);

127.// 动画持续 时间为2秒

128.anim.duration = 2.0;

129.// 旋转的目标值是  转10圈 - btnInitialAngle

130.anim.toValue = @(M_PI * 20 - btnInitialAngle);

131.// 动画效果  淡进 淡出

132.anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

133.// 代理,动画完成后,会通知代理

134.anim.delegate = self;

135.// 让其所在的图层开始假的 快速旋转动画

136.[_circleBgView.layer addAnimation:anim forKey:nil];

137.}

138.#pragma mark - 动画代理方法,动画执行完毕后自动调用

139.- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

140.{

141.// 1.允许交互了

142.self.userInteractionEnabled = YES;

143.// 从transform用公式 算出角度

144.// #define ILTransform2Angle(transform) atan2(transform.b, transform.a)

145.// 2. 算出被点击的按钮的初始角度

146.CGFloat btnInitialAngle = ILTransform2Angle(_circleBgView.selectedBtn.transform);

147.// 3. 让被点击的按钮 指向正上方,即让图层 真正地转 负btnInitialAngle度

148._circleBgView.transform = CGAffineTransformMakeRotation(-btnInitialAngle);

149.

150.// 通知代理(控制器) 被点击的按钮的tag

151.if ([_delegate respondsToSelector:@selector(circleView:didRoateToIndex:)]) {

152.[_delegate circleView:self didRoateToIndex:_circleBgView.selectedBtn.tag];

153.}

154.// 4.继续慢悠悠地转

155.[self performSelector:@selector(startSlowlyRotate) withObject:nil afterDelay:1];

156.}

157.

158.#pragma mark 供控制器调用,让圆转盘,开始慢悠悠地转

159.- (void)startSlowlyRotate

160.{

161.// NSTimer        只适合做频率比较低的事情

162.// CADisplayLink  适合做频率比较高的事情

163.if (_timer.isPaused) {

164.// 如果CADisplayLink仅仅是暂停状态,那么取消暂停

165._timer.paused = NO;

166.} else {

167.// 先停止旧的 CADisplayLink

168.[_timer invalidate];

169.// 再创建新的 CADisplayLink,每1/60秒,调用一次self的rotating:方法

170._timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(slowlyRotating:)];

171.[_timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

172.}

173.}

174.// 重点~~~ 慢悠悠地旋转

175.// 1秒调用60次,1/60.0秒调用一次

176.- (void)slowlyRotating:(CADisplayLink *)timer

177.{

178.// 速度 : 1秒种转多少度

179.// #define ILCircleRotateSpeedPerSecond (M_PI_4/2)

180.

181.// 时间 * 速度 == 角度

182.CGFloat angle = timer.duration * ILCircleRotateSpeedPerSecond;

183.

184.// 旋转一定的角度

185._circleBgView.transform = CGAffineTransformRotate(_circleBgView.transform, angle);

186.

187.}

188.// 计时器暂停,便可以暂停圆盘的旋转

189.- (void)pauseRotate

190.{

191.// 暂停计时器 CADisplayLink

192._timer.paused = YES;

193.}

194.// 停止圆盘的转动,并且清空计时器

195.- (void)stopRotate

196.{

197.[_timer invalidate];

198._timer = nil;

199.}

200.

201.

202.@end


view sourceprint?

01.//

02.//  CircleViewDelegate.h

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-31.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  CircleView

08.

09.#import <Foundation/Foundation.h>

10.@class CircleView;

11.@protocol CircleViewDelegate <NSObject>

12.

13.

14.

15.@optional

16.- (void)circleView:(CircleView *)circleView willRoateToIndex:(NSUInteger)index;

17.- (void)circleView:(CircleView *)circleView didRoateToIndex:(NSUInteger)index;

18.

19.@end


幸运转盘CircleView的背景层是:CircleBgView,

其中背景层CircleBgView又包括三层,

分别是图片1(背景圆盘, 要扣图),图片2(带棱角的转盘),12个星座按钮(CircleItem)

view sourceprint?

01.//

02.//  CircleBgView.h

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-30.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  幸运转盘CircleView的背景层是:CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1(背景圆盘, 要扣图),图片2(带棱角的转盘),12个星座按钮(CircleItem)

08.//  背景层(3层:最底部圆盘图片、中间转盘图片、顶部的星座小图片)

09.

10.#import <UIKit/UIKit.h>

11.

12.@class CircleItem;

13.

14.// 在.h文件中声明 变量的存在

15.extern const int ILCircleWH;

16.

17.

18.

19.@interface CircleBgView : UIView

20.

21.// 类方法,返回一个实例对象

22.+ (instancetype)circleBgView;

23.

24.// 需要根据不同的按钮的i值,利用CGImageCreateWithImageInRect方法,从大图片中裁剪出一张小图片作为按钮的背景图片

25.- (void)set12BtnsBgWithBigImg:(NSString *)normal selected:(NSString *)selected;

26.

27.// 供外界访问,其内部的当前被点击中的 星座按钮

28.@property (nonatomic, readonly) CircleItem *selectedBtn;

29.

30.@end

view sourceprint?

001.//

002.//  CircleBgView.m

003.//  25_彩票

004.//

005.//  Created by beyond on 14-8-30.

006.//  Copyright (c) 2014年 com.beyond. All rights reserved.

007.//  幸运转盘CircleView的背景层是:CircleBgView,其中背景层CircleBgView 又包括三层,分别是图片1(背景圆盘, 要扣图),图片2(带棱角的转盘),12个星座按钮(CircleItem)

008.//  背景层(3层:最底部圆盘图片、中间转盘图片、顶部的星座小图片)

009.

010.#import "CircleBgView.h"

011.

012.// 一个自定义的星座按钮

013.#import "CircleItem.h"

014.// 在.m中定义变量

015.const int ILCircleWH = 286;

016.

017.

018.@implementation CircleBgView

019.

020.

021.#pragma mark - 生命周期方法

022.// 类方法,返回一个实例对象

023.+ (instancetype)circleBgView

024.{

025.return [[self alloc] init];

026.}

027.

028.- (id)initWithFrame:(CGRect)frame

029.{

030.self = [super initWithFrame:frame];

031.if (self) {

032.self.backgroundColor = [UIColor clearColor];

033.// 1.添加12个的代表星座或生肖的按钮

034.[self add12Btns];

035.}

036.return self;

037.}

038.// 1.添加12个的代表星座或生肖的按钮

039.- (void)add12Btns

040.{

041.for (int i = 0; i < 12; i++) {

042.// 按钮内部会 设置自己的锚点 btn.layer.anchorPoint = CGPointMake(0.5, 1);

043.// 设置按钮所在图层的锚点(底部中点),坐标系以左上角为 0 0,x向右为正,y向下为正

044.// 目的是让所有的按钮在添加的时候,可以围绕锚点,即大圆图片的中心点进行rotate

045.

046.CircleItem *btn = [CircleItem buttonWithType:UIButtonTypeCustom];

047.// 绑定tag,目的是要告诉代理,点击了哪一个按钮

048.btn.tag = i;

049.

050.// 设置每个代表生肖的按钮的位置和角度

051.// 锚点的x在圆盘的中心,锚点的y也在圆盘的中心,仅仅变化的是代表星座的按钮的角度

052.CGFloat posX = ILCircleWH * 0.5;

053.CGFloat posY = posX;

054.btn.layer.position = CGPointMake(posX, posY);

055.// 仅仅根据i,设置每一个代表星座的按钮的旋转角度

056.btn.transform = CGAffineTransformMakeRotation(M_PI / 6 * i);

057.// 监听按钮点击

058.[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];

059.[self addSubview:btn];

060.// 第0个默认选中

061.if (i == 0) {

062.[self btnClick:btn];

063.}

064.}

065.}

066.// 需要根据不同的按钮的i值,利用CGImageCreateWithImageInRect方法,从大图片中裁剪出一张小图片作为按钮的背景图片

067.- (void)set12BtnsBgWithBigImg:(NSString *)normal selected:(NSString *)selected

068.{

069.// 遍历12个按钮,根据其i值,裁剪不同的位置的小图片,作为其背景图片

070.for (int i = 0; i<12; i++) {

071.CircleItem *btn = self.subviews[i];

072.// 加载大图片

073.UIImage *normalBig = [UIImage imageNamed:normal];

074.// 裁剪小图片 (像素坐标转成点坐标,在retina坐标下,比例因子为2,一个点代表2个像素)

075.CGFloat miniW = normalBig.size.width / 12 * [UIScreen mainScreen].scale;

076.CGFloat miniH = normalBig.size.height * [UIScreen mainScreen].scale;

077.// 根据i值不同,裁剪不同的rect

078.CGRect miniRect = CGRectMake(i * miniW, 0, miniW, miniH);

079.// 创建出小图片

080.CGImageRef miniNormalCG = CGImageCreateWithImageInRect(normalBig.CGImage, miniRect);

081.// 设置裁剪出来的小图片为按钮的背景

082.[btn setImage:[UIImage imageWithCGImage:miniNormalCG] forState:UIControlStateNormal];

083.

084.// 选中时的背景图片,也是一样的裁剪后,设置到按钮的选中状态下背景图片

085.UIImage *selectedBig = [UIImage imageNamed:selected];

086.CGImageRef miniSelectedCG = CGImageCreateWithImageInRect(selectedBig.CGImage, miniRect);

087.[btn setImage:[UIImage imageWithCGImage:miniSelectedCG] forState:UIControlStateSelected];

088.}

089.}

090.// 三步曲,控制按钮点击时的切换

091.- (void)btnClick:(CircleItem *)btn

092.{

093._selectedBtn.selected = NO;

094.btn.selected = YES;

095._selectedBtn = btn;

096.}

097.

098.#pragma mark - 父类的方法

099.// setFrame:和setBounds:能保证尺寸永远是286x286

100.- (void)setFrame:(CGRect)frame

101.{

102.frame.size = CGSizeMake(ILCircleWH, ILCircleWH);

103.[super setFrame:frame];

104.}

105.

106.- (void)setBounds:(CGRect)bounds

107.{

108.bounds.size = CGSizeMake(ILCircleWH, ILCircleWH);

109.[super setBounds:bounds];

110.}

111.

112.#pragma mark - 重点,绘图

113.// 背景圆盘(需要扣图处理)LuckyBaseBackground.png

114.- (void)drawRect:(CGRect)rect

115.{

116.// 1.画最底部的背景圆盘

117.// 取得当前view的上下文,不须再重新创建上下文对象

118.CGContextRef ctx = UIGraphicsGetCurrentContext();

119.// copy一个ctx对象到栈中,保存现场,并且会复制出一个新的上下文.

120.// 在还原现场之前的所有操作,都将在这个新的上下文中执行

121.CGContextSaveGState(ctx);

122.

123.// 2.在上下文中画一个小点的圆,并裁剪掉上下文,最后将背景圆盘绘制到稍小的圆形上下文中

124.// 2.1.画一个稍小些的圆

125.CGFloat innerCircleXY = 9;

126.CGFloat innerCircleWH = ILCircleWH - innerCircleXY * 2;

127.CGRect innerCircleRect = CGRectMake(innerCircleXY, innerCircleXY, innerCircleWH, innerCircleWH);

128.// 在上下文中的指定坐标处画一个指定大小的圆

129.CGContextAddEllipseInRect(ctx, innerCircleRect);

130.

131.// 2.2.裁剪(CGContextClip会把之前所画的剪下来)

132.// 意思是 将上下文中 不属于刚才 画的圆的东东,全部清空(清空小圆以外的东东)

133.// 上下文中现在只剩下一个稍小的圆形了

134.CGContextClip(ctx);

135.// 2.3.将稍大的背景圆盘图片 画到刚才裁剪后的上下文中,即为小圆形的上下文中

136.// (因为小圆形以外的上下文区域 已经被清空了)

137.[[UIImage imageNamed:@"LuckyBaseBackground"] drawInRect:rect];

138.

139.// 3.为了画下一张转盘图,因为不须要裁剪,所以恢复现场,还原为以前的正常的rect的上下文(没被裁剪的rect)

140.CGContextRestoreGState(ctx);

141.

142.// 4.画中间的完整的转盘图 到上下文中

143.[[UIImage imageNamed:@"LuckyRotateWheel"] drawInRect:rect];

144.}

145.

146.

147.@end

CircleItem继承自按钮,

一个本类实例,就代表着一个可被点击的星座或
生肖

view sourceprint?

01.//

02.//  CircleItem.h

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-30.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  CircleItem 继承自按钮,一个本类实例,就代表着一个可被点击的星座 或 生肖

08.

09.#import <UIKit/UIKit.h>

10.

11.@interface CircleItem : UIButton

12.

13.@end

view sourceprint?

01.//

02.//  CircleItem.m

03.//  25_彩票

04.//

05.//  Created by beyond on 14-8-30.

06.//  Copyright (c) 2014年 com.beyond. All rights reserved.

07.//  继承自按钮,一个本类实例,就代表着一个可被点击的星座 或 生肖

08.

09.#import "CircleItem.h"

10.

11.// 生肖 或 星座按钮的宽和高,须与提供的图片一致

12.const int kCircleItemWidth = 68;

13.const int kCircleItemHeight = 143;

14.

15.@implementation CircleItem

16.#pragma mark - 生命周期方法

17.- (id)initWithFrame:(CGRect)frame

18.{

19.self = [super initWithFrame:frame];

20.if (self) {

21.// 设置按钮选中时的背景

22.[self setBackgroundImage:[UIImage imageNamed:@"LuckyRototeSelected.png"] forState:UIControlStateSelected];

23.// 设置按钮所在图层的锚点(底部中点),坐标系以左上角为 0 0,x向右为正,y向下为正

24.// 目的是让所有的按钮在添加的时候,可以围绕锚点,即大圆图片的中心点进行rotate

25.self.layer.anchorPoint = CGPointMake(0.5, 1);

26.}

27.return self;

28.}

29.

30.#pragma mark - 父类的方法

31.// 重写setFrame:和setBounds:能保证尺寸永远是68x143

32.- (void)setFrame:(CGRect)frame

33.{

34.frame.size = CGSizeMake(kCircleItemWidth, kCircleItemHeight);

35.[super setFrame:frame];

36.}

37.- (void)setBounds:(CGRect)bounds

38.{

39.bounds.size = CGSizeMake(kCircleItemWidth, kCircleItemHeight);

40.[super setBounds:bounds];

41.}

42.// 中须选中,不要高亮状态

43.- (void)setHighlighted:(BOOL)highlighted {}

44.// 调整按钮的图片的位置

45.- (CGRect)imageRectForContentRect:(CGRect)contentRect

46.{

47.// 获得当前屏幕点的比例,如果是2.0代表retina视网膜屏幕,一个点代表2个像素

48.CGFloat scale = [UIScreen mainScreen].scale;

49.// 获得图片本身的大小,从而进行 缩小 为正常的点坐标

50.CGSize size = [self imageForState:UIControlStateNormal].size;

51.

52.// 除以比例因子,得到点坐标下的正常的size

53.CGFloat w = size.width/scale;

54.CGFloat h = size.height/scale;

55.// 设置x y坐标

56.CGFloat x = ( contentRect.size.width - w ) * 0.5;

57.CGFloat y = ( contentRect.size.height - h ) * 0.5 - 20;

58.// 返回调整好的图片的frame

59.return  CGRectMake(x, y, w, h);

60.}

61.

62.#pragma mark - 触摸事件二大方法

63.// 点击按钮的时候必定会调用

64.// 询问鼠标点击的point是否在按钮身上

65.// 如果返回YES,代表point在按钮身上,系统就会让按钮处理点击事件

66.// 如果返回NO,代表point部在按钮身上,系统就不会让按钮处理点击事件

67.- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

68.{

69.NSLog(@"----%@", NSStringFromCGPoint(point));

70.return [super pointInside:point withEvent:event];

71.}

72.- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

73.{

74.return [super hitTest:point withEvent:event];

75.}

时间: 2024-10-06 00:53:30

【转】iOS25彩票 幸运转盘的相关文章

iOS_26彩票_幸运转盘

最终效果图: 各个view的关系图: 背景圆盘(需要扣图处理)LuckyBaseBackground.png 盖在背景圆盘上面的转盘 LuckyRotateWheel.png 代表一个星座或生肖的按钮背景图片 要创建12个,并以最下方中点为锚点进行旋转 对背景圆盘进行扣图,并在其上面盖上转盘图片的核心代码 在自定义的背景view中,画好了背景圆盘和背景转盘之后, 一次性添加12个代表星座或生肖的按钮,并设置旋转角度 一张集合了所有的代表星座的按钮的背景图片的大图片 一张集合了所有的代表星座的按钮

[iOS UI进阶 - 2.4] 彩票Demo v1.4 转盘动画

A.需求 幸运广场界面中有一个幸运转盘,平时能够自动缓缓转动 能够选择星座 点击“开始选号”开速旋转转盘,旋转一定周数 转盘转动速度节奏:开始-慢-块-慢-结束 设置其余的背景和按钮 code source: 彩票Demo https://github.com/hellovoidworld/HelloLottery 转盘Demo https://github.com/hellovoidworld/LuckyWheelDemo B.实现 1.使用xib设计转盘 2.自定义类 (1)自定义一个继承U

微信公众平台消息接口开发 彩票查询

一.获取数据 目前很多网站都提供彩票信息查询,所以取得彩票数据是件很容易的事.方倍工作室开发出彩票查询接口 API,目前已开通'双色球','3D','七乐彩','大乐透','七星彩','排列3','排列5','胜负彩','六场半全场','四场进球' 10种数据,每日同步更新 使用方式为直接在URL中提交彩票名称即可,名称需要先做urlencode调用url方法:以下是调用双色球方法 http://api2.sinaapp.com/search/lottery/?appkey=0020130430

彩票机选器

今天用python写了个彩票机选器,功能很简单,仅供娱乐.还请大家来斧正! 下面是这个小程序的代码: #coding=utf8 n=15 i=1 m=range(1,n) import time from random import randint print '请选择彩票种类:1为双色球2为大乐透' print '请输入:', t=input() print '正在为你机选,请稍候.' time.sleep(1) print '以下为本次机选号码' if t==1:     while i<=

浅谈模拟彩票代码,html,javascript

今天简单介绍一下用html,javascript来模拟双色球彩票选择器. 双色球彩票规则:由6个红球和1个蓝球组成,其中6个红球是从1-33中随机选出的不重复的6个数,从小到大一次排列:蓝球是1-16随机生成的一个数 1.创建红球数组,随机生成1-33的6个不重复的数字,并放入红球数组中,2.将数组中6个数字从小到大进行排列 3.将数组中的数字依次放入6个红球中,4.最后将随机生成的1-16中的一个数字放入最后的蓝球中.效果如图所示: 首先用css进行简单的样式设置 用javascript来模拟

(素材源码)猫猫学iOS(四十六)之网易彩票幸运大转盘

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 素材源码地址:http://download.csdn.net/detail/u013357243/8713827 效果 代码: NYWheel NYWheel.h // // NYWheel.h // 网易彩票幸运大转盘 // // Created by apple on 15-5-18. // Copyright (c)

iOS菜鸟成长笔记(2)——网易彩票练习(1)

距离上一篇<第一个iOS应用>已经有一个多月了,今天来和大家一起学习和分享一下一个小练习<网易彩票> 首先我们向storyboard中拖入一个TabBarController和5个NavigationController,如下: 我们先来看看什么是导航控制器 1.导航控制器 "如果应用程序有多个内容视图层次,就需要能够在它们之间进行切换.为此,可以使用专门的视图控制器:导航控制器 (UINavigationController).导航控制器管理在一系列视图控制器中向后和向

《世界杯彩票竞猜系统》设计报告

目录 1 文档介绍    4 1.1 文档目的    4 1.2 文档范围    4 1.3 读者对象    4 1.4 参考文献    5 1.5 术语与缩写解释    5 2 系统环境说明    6 3 需求分析    7 3.1 功能需求分析    7 3.2 非功能需求分析    7 4 数据库的命名规则    8 5 概念结构设计    9 6 逻辑结构设计    9 7 物理结构设计    11 7.1 表汇总    11 7.2 表VS    11 7.3 表team    12

如何买世界杯决赛彩票

德国:阿根廷 :2.10  2.92  3.30 巴西:荷兰    :1.90  3.65  3.10 世界杯决赛马上就要开始,有上面俩场比赛(赔率如上),小渊现在准备投入200元买彩票(每张彩票2元,需2串1).怎样买,小渊的收益最大? 假设德国队的胜负率分别为x,y.巴西的胜负率分别为a,b. #include "stdafx.h" #include <vector> using namespace std; typedef struct { int sum; int