iOS 抽奖转盘 练习demo

组里到了新的6+,为了搞一轮抽奖写了这个抽奖程序。是哒我们就是如此调皮~

首先我们要有权重数据,最近在看权利的游戏,给喜欢的人物加分:

 1     NSDictionary *dataDic = [NSDictionary
 2                              dictionaryWithObjectsAndKeys:
 3                              @(1),@"Jamie",
 4                              @(1),@"Cersei",
 5                              @(1),@"Joffery",
 6                              @(3),@"Imp",
 7                              @(1),@"Ned",
 8                              @(4),@"Arrey",
 9                              @(2),@"Shae",
10                              @(2),@"Sansa",
11                              @(4),@"Margaery",
12                              @(2),@"Baelish",
13                              nil];

接下来就是画转盘。我们要画一个不管数据是什么都能够完美展现的转盘。转盘的公平性就在于对 360度要根据每个人的权重进行均分。那么我们首先就要对权重数据进行处理,将权重变成角度。

 1 - (void)setData:(NSDictionary*)dataDic
 2 {
 3     self.cornerDic = [[NSMutableDictionary alloc]init];
 4     int totalCount = 0;
 5     for (NSString *key in dataDic) {
 6         totalCount += [(NSNumber*)dataDic[key] intValue];
 7     }
 8
 9     for (NSString *key in dataDic) {
10         double corner = [(NSNumber*)dataDic[key] doubleValue]/(double)totalCount * 360;
11         [self.cornerDic setObject:@(corner) forKey:key];
12     }
13 }

好了现在数据已备好,可以开始画了。画转盘的关键有两点:1.如何画扇形; 2.如何把人名旋转一个合适的角度让它正确的显示在对应的扇形上。

虽然之前知道可以通过重写drawRect绘制扇形,但总感觉这种方法有一丢丢的挫,因为你不能掌控这个drawRect什么时候会被调用,有种不可控的感觉,但是查遍了祖国大地也只找到这么一个方法,所以就先用这个了。其实就是一笔一划的画出来再填色。

1 static inline void drawArc(CGContextRef ctx, CGPoint point, float radius,float angle_start, float angle_end, UIColor* color) {
2     CGContextMoveToPoint(ctx, point.x, point.y);
3     CGContextSetFillColor(ctx, CGColorGetComponents( [color CGColor]));
4     CGContextAddArc(ctx, point.x, point.y, radius,  angle_start, angle_end, 0); //这个0表示顺时针画弧,1就是逆时针
5     CGContextFillPath(ctx);
6 }

那么为什么一定要在drawRect里写绘制的代码呢?在外面行不行呢?貌似是不行。(如果以后知道有会贴回来)因为所有的绘制都需要一个“上下文环境”。而这个上下文只有在drawRect里才能获取到值,在外面拿到的都是nil。

“The current graphics context is nil by default. Prior to calling its drawRect: method, view objects push a valid context onto the stack, making it current. If you are not using a UIView object to do your drawing, however, you must push a valid context onto the stack manually using the UIGraphicsPushContext function.”

 1 - (void)drawRect:(CGRect)rect
 2 {
 3     CGContextRef ctx = UIGraphicsGetCurrentContext();
 4     CGContextClearRect(ctx, rect);
 5
 6     srand((unsigned)time(0));
 7
 8     CGPoint center = CGPointMake(self.frame.size.width/2, self.frame.size.width/2);
 9
10     float angle_start = 0;
11     float angle_end = 0;
12     int i = 0;
13
14
15     UIColor *yelloColor = [UIColor colorWithRed:249/255.0 green:226/255.0 blue:55/255.0 alpha:1];
16     UIColor *redColor = [UIColor colorWithRed:247/255.0 green:148/255.0 blue:53/255.0 alpha:1];
17     for (NSString *key in self.cornerDic) {
18 //        if ([key isEqualToString:@"Imp"]) {
19
20         angle_start = angle_end;
21         angle_end = angle_start+ radians([(NSNumber*)self.cornerDic[key] doubleValue]);
22
23         UIColor *color = nil;
24         if (i%2 == 0) {
25             color = yelloColor;
26         }
27         else
28         {
29             color = redColor;
30         }
31         drawArc(ctx, center, self.frame.size.width/2-self.layer.borderWidth, angle_start, angle_end, color);
32         i++;
33
34         CATextLayer *txtLayer = [self textLayer:key rotate:angle_start + (angle_end-angle_start)/2];
35         [self.layer addSublayer:txtLayer];
36 //        }
37     }
38 }

画人名我用了CATextLayer这个东西,可设置的东西还挺多的。我把文字设置在右边,这样旋转角更好设置。我在调试过程中经常把控件的背景颜色变成醒目的颜色,这样更好调试UI。

 1 - (CATextLayer*)textLayer:(NSString*)text rotate:(CGFloat)angel
 2 {
 3     CATextLayer *txtLayer = [CATextLayer layer];
 4     txtLayer.frame = CGRectMake(0, 0, self.frame.size.width-self.layer.borderWidth*2-2, 25);
 5     txtLayer.anchorPoint = CGPointMake(0.5, 0.5); //绕中心点旋转
 6     txtLayer.string = text;
 7     txtLayer.alignmentMode = [NSString stringWithFormat:@"right"];
 8     txtLayer.fontSize = 18;
 9     [txtLayer setPosition:CGPointMake(self.frame.size.width/2, self.frame.size.width/2)];//Position大致就是center的概念
10     txtLayer.transform = CATransform3DMakeRotation(angel,0,0,1);
11     return txtLayer;
12 }

最后就是让这个转盘旋转起来

 1 - (void)turnTheTable
 2 {
 3     CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
 4     double endValue = _startValue+(rand()%100)/100.0 * M_PI + M_PI*(rand()%5+5);
 5
 6     rotationAnimation.fromValue = @(_startValue);
 7     rotationAnimation.toValue = @(endValue);
 8     rotationAnimation.duration = (endValue - _startValue)/(M_PI*2);
 9     rotationAnimation.autoreverses = NO;
10     rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
11     rotationAnimation.removedOnCompletion = NO;
12     rotationAnimation.fillMode = kCAFillModeBoth;
13     [self.turnTableView.layer addAnimation:rotationAnimation forKey:@"TurnTableAnimation"];
14     _startValue = endValue;
15 }

工程地址:https://github.com/MeowWang/LotteryTurnTable

转载请注明出处

时间: 2024-10-28 11:23:16

iOS 抽奖转盘 练习demo的相关文章

利用java实现抽奖转盘(着重安全控制)

本文是针对jquery 实现抽奖转盘作者的一个补充(主要用java去实现转盘结果生成及存储,解决jquery 做法 非法用户采用模拟器实现改变转盘值的风险性),针对jQuery的具体实现,请看案例:http://www.cnblogs.com/mofish/archive/2013/01/24/2875516.html              本文就不一一细说了,那么现在就直入正题. 由于公司产品推广,最近要求实现一个邀请用户注册即可抽奖的转盘,页面展示如下: java 实现方式如下: 构造实

一个简单的抽奖转盘游戏

在一个项目中要做一个游戏,在这个过程中做了一个简单的9宫格抽奖游戏.大体思路是,点击开始按钮,游戏开始.由一个逐步递增参数 drawStep 来控制格子的背景颜色的改变,游戏停止的位置参数 stopPosition 由随机函数生成,以此来控制格子停止的位置.游戏转动一圈是8个格子,5圈就是40.easeTime参数模拟格子转动的缓步启动和缓步停止. <!doctype html> <html> <head> <meta charset="gbk"

利用canvas实现抽奖转盘

之前做过的项目中,有需要抽奖转盘功能的.项目已经完工一段时间了,也没出现什么严重的bug,所以现在拎出来分享给大家. 功能需求 转盘要美观,转动效果流畅. 转盘上需要显示奖品图片,并且奖品是后台读取的照片和名字. 转动动画完成后要有相应提示. 获取的奖品具体算法在数据库里操作,前端只提供最后的效果展示. 知识要点 引用了一个jq插件:awardRotate,用来实现更智能化的转动(插件下载:http://www.jqcool.net/jquery-jqueryrotate.html). 使用ca

iOS多线程开发小demo

首先演示一下主线程的阻塞 // DYFViewController.m // 623-01-阻塞多线程 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @end @implementation DYFViewCon

模仿抽奖转盘,并且用cookie记录历史次数

自己制作了一个模仿抽奖转盘的小游戏,代码比较简单,规则是只有三次抽奖机会,并且浏览器会记录抽奖的次数, 代码如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-sca

一个iOS图片选择器的DEMO(实现图片添加,宫格排列,图片长按删除,以及图片替换等功能)

在开发中,经常用到选择多张图片进行上传或作其他处理等等,以下DEMO满足了此功能中的大部分功能,可直接使用到项目中. 主要功能如下: 1,图片九宫格排列(可自动设置) 2,图片长按抖动(仿苹果软件删除时,图标抖动效果),可进入删除状态,再次单击进入普通状态 3,图片设置最大上限,加号按钮自动隐藏 4,已选图片可单击进行重新选择 5,无需代理,直接调用对应属性就可获取所有图片,并与显示顺序保持一致 效果图如下: 1 // 2 // SZAddImage.h 3 // addImage 4 // 5

九宫格抽奖转盘源码分析

效果如上图所示,下面对其实现代码进行分析,看能不能破解其抽奖规则.需要引入jquery-1.8.3.min.js和images/9张图片. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.or

Android实现抽奖转盘

慕课网视频 今天学习了以下抽奖转盘的实现 首先学习了以下 SurfaceView 的一般使用方法 下面的代码是 写 SurfaceView 的一个模板 package com.negro.myluckypan; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.SurfaceHolder; import andr

css 如何“画”一个抽奖转盘

主要描述的是如何运用 css 绘制一个抽奖转盘,并运用原生 js 实现转盘抽奖效果. 先来张效果图: 布局 一般来说,转盘一般有四个部分组成:外层闪烁的灯.内层旋转的圆盘.圆盘上的中奖结果.指针. 所以html的结构如下: <div class="turntable-wrap"> <div class="light" id="turntable_light"></div> <div class="