最近公司让写一个转盘积分抽奖的样式,所以把创建过程中的心得记录一下,给大家分享

首先创建了相关的图片转盘,指针图片,然后就是考虑转盘如何旋转的问题,我是通过给指针图片添加一个动画效果,从而实现旋转效果

//我的积分,抽奖按钮
    UIView *bgView1 = [[UIView alloc]initWithFrame:CGRectMake(0, 64, f_Device_w, 60)];
    [self addTopBgView:bgView1];
    [self.view addSubview:bgView1];
    
    //添加转盘
    _image_disk = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"disk.jpg"]];
    _image_disk.frame = CGRectMake((f_Device_w-300)/2, 145, 300, 300);
    [self.view addSubview:_image_disk];
    
    //添加转针
    _image_start = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"start.png"]];
    _image_start.frame = CGRectMake(0, 0, 110.0, 220.0);
    _image_start.center = CGPointMake(_image_disk.center.x+3, _image_disk.center.y);
    [self.view addSubview:_image_start];

当点击抽奖按钮时,添加旋转动画效果,详细代码中,我对必要的地方进行了代码说明,在这里主要说一下,srand((unsigned)time(0)); 这句话的含义:

用0调用时间函数time(),将其返回值强制转换为unsigned型,作为参数来调用srand( )函数。srand( )是为rand( )函数初始化随机发生器的启动状态,
以产生伪随机数,所以常把srand( )称为种子函数。用time()返回的时间值做种子的原因是time()返回的是实时时间值,每时毎刻都在变化,
这样产生的伪随机数就有以假乱真的效果。
这句话是根据不同的时间点,产生不同的随机数序列,如果觉得时间间隔比较小,可以适当地乘以一个整数值;
如果不加这句系统会默认调用srand()函数,并且初始值为1,然后每次产生的随机数序列是不变的,效果不太好

函数rand()是真正的随机数生成器,而srand()会设置供rand()使用的随机数种子。函数rand()会返回一个处于0和你所指定的数值(缺省为1)之间的分数。如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。而使用同种子相同的数调用srand()会导致相同的随机数序列被生成。
    srand((unsigned)time(NULL))则使用系统定时/计数器的值做为随机种子,所以,在相同的平台环境下,显示的随机数会是伪随机数,即每次运行显示的结果会有不同。
    库函数中系统提供了两个函数用于产生随机数:srand()和rand()。

原型为:

函数一:int rand(void);
    从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。

函数二:void srand(unsigned seed);
    参数seed是rand()的种子,用来初始化rand()的起始值。

但是,要注意的是所谓的“伪随机数”指的并不是假的随机数。其实绝对的随机数只是一种理想状态的随机数,计算机只能生成相对的随机数即伪随机数。计算机生成的伪随机数既是随机的又是有规律的 —— 一部份遵守一定的规律,一部份则不遵守任何规律。

系统在调用rand()之前都会自动调用srand(),如果用户在rand()之前曾调用过srand()给参数seed指定了一个值,那么rand()就会将seed的值作为产生伪随机数的初始值;而如果用户在rand()前没有调用过srand(),那么系统默认将1作为伪随机数的初始值。如果给了一个定值,那么每次rand()产生的随机数序列都是一样的~~

所以为了避免上述情况的发生我们通常用srand((unsigned)time(0))或者srand((unsigned)time(NULL))来产生种子。如果仍然觉得时间间隔太小,可以在(unsigned)time(0)或者(unsigned)time(NULL)后面乘上某个合适的整数。例如,srand((unsigned)time(NULL)*10)

另外,关于time_t time(0):time_t被定义为长整型,它返回从1970年1月1日零时零分零秒到目前为止所经过的时间,单位为秒。

关于求值区域的问题:要取得[a,b)之间的随机整数,使用(rand() % (b-a))+ a (结果值将含a不含b)。
在a为0的情况下,简写为rand() % b。

代码中我将控制和非控制的情况进行了分开编写,可以看看

//******************旋转动画******************
    //产生随机角度
    srand((unsigned)time(0)); 
    random = (rand() % 20) / 10.0;//0.0--1.9
    //NSLog(@"输出此时的随机数。。。。000.....%f",random);
    //设置动画
    CABasicAnimation *spin = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    //开始位置
    [spin setFromValue:[NSNumber numberWithFloat:M_PI * (0.0+orign)]];
    
    /*
    //-------------------这是人为不控制得奖概率时的代码
    //结束位置
    [spin setToValue:[NSNumber numberWithFloat:M_PI * (10.0+random+orign)]];
    [spin setDuration:3.0];
    [spin setDelegate:self];//设置代理,可以相应animationDidStop:finished:函数,用以弹出提醒框
    //速度控制器
    [spin setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    //添加动画
    [[_image_start layer] addAnimation:spin forKey:nil];
    //锁定结束位置
    _image_start.transform = CGAffineTransformMakeRotation(M_PI * (10.0+random+orign));
    //再次抽奖时,锁定fromValue的位置
    orign = 10.0+random+orign;
    NSLog(@"......输出此时origin...111.....%f",orign);
    //浮点取余
    orign = fmodf(orign, 2.0);
    NSLog(@"......输出此时origin...222......%f",orign);*/
    
    //-----------------这是人为控制得奖概率
    //结束位置,这个地方可以修改数据,然后控制不同奖项的得奖概率
    //首先根据表盘的设计,判断指针停在何处有利于公司的利益,从我设计的积分来看,只有获得一等奖6分或二等奖5分,才算是中奖,在表盘上的概率占到了1/6,这个几率有点大,如果你要是有大奖的话,就需要控制得大奖的概率问题,这里我们可以判断一下值,然后根据需要进行偏移,比如说,指针只有在一等奖或二等奖的面积的一半范围内,才能得奖,这样就把获得一等奖或二等奖的概率减少到了1/12,(添加一个10,相当于多转了五圈)
    CGFloat currentF1 = 10.0+random+orign;
    //浮点取余
    CGFloat currentF2 = fmodf(currentF1, 2.0);
    if (currentF2>(0.25/3.0) && currentF2<=(0.5/3.0))
    {
        currentF1 = currentF1+0.0833;
        //NSLog(@"经过改变后的概率值111。。。。。。%f",currentF1);
    }
    if (currentF2>((0.5/3.0+0.25/3.0)+1.5) && currentF2 < (((0.5/3.0)*2)+1.5))
    {
        currentF1 = currentF1+0.0833;
        //NSLog(@"经过改变后的概率值222。。。。。。%f",currentF1);
    }
    [spin setToValue:[NSNumber numberWithFloat:M_PI * currentF1]];
    [spin setDuration:3.0];
    [spin setDelegate:self];//设置代理,可以相应animationDidStop:finished:函数,用以弹出提醒框
    //速度控制器
    [spin setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    //添加动画
    [[_image_start layer] addAnimation:spin forKey:nil];
    //锁定结束位置
    _image_start.transform = CGAffineTransformMakeRotation(M_PI * currentF1);
    //锁定fromValue的位置
    orign = currentF1;
    //NSLog(@"......输出此时origin...111.....%f",orign);
    //浮点取余
    orign = fmodf(orign, 2.0);
    //NSLog(@"......输出此时origin...222......%f",orign);

通过点击按钮添加的动画效果,然后实现代理的方法,完成对应的得奖提醒信息

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    //判断抽奖结果
    if (orign >= 0.0 && orign < (0.5/3.0)) {
        [self showAlertViewTitle:@"恭喜中奖!" infoS:@"您中了 一等奖,奖励6分!" intrgralPrizeS:@"6"];
    }

else if (orign >= (0.5/3.0) && orign < ((0.5/3.0)*2))
    {
        [self showAlertViewTitle:@"恭喜中奖!" infoS:@"您中了 七等奖,奖励1分!" intrgralPrizeS:@"1"];

}

}

结果显示:

                  

源码地址:http://download.csdn.net/detail/hbblzjy/9619291

iOS积分抽奖Demo,可以人为控制不同奖项的得奖率的更多相关文章

  1. socket.io简单说明及在线抽奖demo

    socket.io简单说明及在线抽奖demo socket.io 简介 Socket.IO可以实现实时双向的基于事件的通信. 它适用于各种平台,浏览器或设备,也同样注重可靠性和速度. socket.i ...

  2. 李洪强iOS开发Swift篇—06_流程控制

    李洪强iOS开发Swift篇—06_流程控制 一.swift中的流程控制 Swift支持的流程结构如下: 循环结构:for.for-in.while.do-while 选择结构:if.switch 注 ...

  3. Android 自定义View实现QQ运动积分抽奖转盘

    因为偶尔关注QQ运动, 看到QQ运动的积分抽奖界面比较有意思,所以就尝试用自定义View实现了下,原本想通过开发者选项查看下界面的一些信息,后来发现积分抽奖界面是在WebView中展示的,应该是在H5 ...

  4. 最全的iOS物理引擎demo

    概述 最全的iOS物理引擎demo,实现重力.碰撞.推力.摆动.碰撞+重力.重力弹跳.仿摩拜单车贴纸效果.防iMessage滚动效果.防百度外卖首页重力感应等效果! 详细 代码下载:http://ww ...

  5. iOS测试中发现一个textview控制,使用clear()无法清除文字

    iOS测试中发现一个textview控制,使用clear()无法清除

  6. 【转】【iOS知识学习】_视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途

    原文网址:http://blog.csdn.net/weasleyqi/article/details/8090373 iOS视图控制对象生命周期-init.viewDidLoad.viewWillA ...

  7. [转]iOS之浅谈纯代码控制UIViewController视图控制器跳转界面的几种方法

    参考:http://www.mamicode.com/info-detail-469709.html 一.最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能( ...

  8. iOS苹果官方Demo合集

    Mirror of Apple’s iOS samples This repository mirrors Apple’s iOS samples. Name Topic Framework Desc ...

  9. iOS之浅谈纯代码控制UIViewController视图控制器跳转界面的几种方法

    .最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能(ipad我不了解除外,这里只说iPhone),这个方法是所有视图控制器对象都可以用的,而实现这种功能,有 ...

随机推荐

  1. A neural chatbot using sequence to sequence model with attentional decoder. This is a fully functional chatbot.

    原项目链接:https://github.com/chiphuyen/stanford-tensorflow-tutorials/tree/master/assignments/chatbot 一个使 ...

  2. spring boot+mybaits+mysql+generato(逆向工程)+前后台数据交互

    如按照我博客上没有弄出来 请在下面留言 我好修改 谢谢 小弟使用的是Eclipse 首先下载STS插件 help--->Elipse Marketplace--->find搜索栏里面搜索S ...

  3. Thread 调用方法的方式

    1.传统ThreadStart 2.ParameterizedThreadStart 3.委托thread = new Thread(delegate() { NoticeBroadcast(user ...

  4. log4cxx用环境变量设置输出文件名

    log4cxx用环境变量设置输出文件名(金庆的专栏 2016.12)利用环境变量,可以用同一个log4j.xml来配置多个相似进程,输出日志到不同文件.例如多个BaseApp进程使用同一个BaseAp ...

  5. java开源即时通讯软件服务端openfire源码构建

    java开源即时通讯软件服务端openfire源码构建 本文使用最新的openfire主干代码为例,讲解了如何搭建一个openfire开源开发环境,正在实现自己写java聊天软件: 编译环境搭建 调试 ...

  6. 实例演示如何在spring4.2.2中集成hibernate5.0.2并创建sessionFactory

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/49388209 文章作者:苏生米沿 本文目的:使用spring4.2.2集成hibern ...

  7. Dubbo框架应用之(二)--服务治理

    Dubbo服务治理全貌图 当我们现有ITOO平台系统的业务随着用户的逐渐增大,设计的业务越来越广,系统会异常的复杂,在大规模服务之前,我们可以采用的是RMI或Hessian等工具,暴露和引用远程服务, ...

  8. [Python监控]psutil模块简单使用

    安装很简单 pip install psutil 官网地址为 https://pythonhosted.org/psutil/ (文档上有详细的api) github地址为 https://githu ...

  9. Tomcat中的ssl安全信道的实现

    为了实现https协议通信,tomcat需要利用JSSE把SSL/TLS协议集成到自身系统上,通过上一节我们知道不同的厂商可以实现自己的JSSE,而tomcat默认使用的是以前sun公司开发实现的包而 ...

  10. 生活沉思录 via 哲理小故事

    本文转载:http://www.cnblogs.com/willick/p/3174803.html 1.小托蒂的悲剧 意大利小男孩托蒂,有一只十分奇怪的眼睛,因为从生理上看,这是一只完全正常的眼睛, ...