前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS抽奖转盘上篇:概率抽奖算法 & 转盘算法 &轮盘边框动画丨(内含完整Demo)

iOS抽奖转盘上篇:概率抽奖算法 & 转盘算法 &轮盘边框动画丨(内含完整Demo)

作者头像
公众号iOS逆向
发布2022-12-19 17:33:46
9690
发布2022-12-19 17:33:46
举报
文章被收录于专栏:iOS逆向与安全iOS逆向与安全

引言

原理:利用CoreGraphics进行自定义转盘的绘制

视频:https://live.csdn.net/v/158749 下载完整Demo:https://download.csdn.net/download/u011018979/16651799

在app侧控制中奖奖品,有两种方式

方式一:发起网络请求获取当前选中奖品(推荐),即由服务侧控制中奖数据,更安全 方式二:根据奖品百分比进行控制中奖概率

I、根据奖品百分比进行控制中奖概率

  • 根据中奖概率probability 确定随机中奖范围probabilityRange
  • 根据随机中奖范围probabilityRange,确定中奖奖品

1.1 定义奖品模型

代码语言:javascript
复制

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface KNTurntableViewModel : NSObject
@property (nonatomic, assign) NSInteger index;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *imageName;

@property (nonatomic, copy) NSString *icon;
/**
 该奖品的中奖概率
 */
@property (nonatomic, assign) double probability;

//
@property (nonatomic, assign) NSRange probabilityRange;

/**
 根据奖品的中奖概率获取中奖奖品
 */
+(instancetype)getMbyprobabilityRangeWithArr:(NSArray*)arr;

@end

NS_ASSUME_NONNULL_END

1.2 根据奖品的中奖概率获取中奖奖品

  • 根据随机中奖范围probabilityRange,确定中奖奖品
代码语言:javascript
复制
// 根据奖品百分比进行控制:
// 奖品 title A ,index下标0,中奖 概率probability80%, 就是当randomNum为0-80,返回中奖下标0
// 为了便于理解,我们称奖品A的【随机中奖范围】 probabilityRange为0-80
//

// 根据randomNum,确定中奖奖品

+ (instancetype)getMbyprobabilityRangeWithArr:(NSArray *)arr {
    
    
    NSInteger randomNum = arc4random()%100;//控制概率

    NSLog(@"randomNum:%@",[NSNumber numberWithDouble:randomNum]);
    
    
    for (KNTurntableViewModel *obj in arr) {
        
        NSLog(@"obj probabilityRange loc:%@ len %@", [NSNumber numberWithDouble:obj.probabilityRange.location],[NSNumber numberWithDouble:obj.probabilityRange.location+obj.probabilityRange.length]
              );
        
        
        

    
        if (randomNum>=obj.probabilityRange.location && randomNum<obj.probabilityRange.location+obj.probabilityRange.length) {//80%的概率 就是0-80
            
            
            return obj;


        }
        
        
    }
    
    return nil;// 谢谢参与

}


1.3 构造数据模型

  • 根据中奖概率probability 确定随机中奖范围probabilityRange
代码语言:javascript
复制
- (KNTurntableViewM *)viewModel{
    
    if(_viewModel == nil){
        _viewModel = [KNTurntableViewM new];
        
        NSMutableArray * luckyItemArray = [NSMutableArray array];
        
        
        double probabilityRangeLoc = 0;
        double probabilityRangeLen = 0;
        

        
        for (int i = 0; i < 6; i++) {//
            KNTurntableViewModel *model = [[KNTurntableViewModel alloc] init];
            model.title = [NSString stringWithFormat:@"%d-标题",i];
            model.index = i;
            if(i == 1){
                
                model.probability = 0.5;
                
                

            }else{
                model.probability =0.1;

            }
            
            
            // 初始化probabilityRange
            probabilityRangeLoc = probabilityRangeLoc +probabilityRangeLen;
            probabilityRangeLen = i+100*model.probability;
            
            
            //probabilityRange 的计算不要包括谢谢参与的概率
            model.probabilityRange = NSMakeRange(probabilityRangeLoc, probabilityRangeLen);
            
            model.imageName = @"qrcode_for_gh";
            model.icon = @"https://img-blog.csdnimg.cn/20201114103143654.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMTg5Nzk=,size_16,color_FFFFFF,t_70#pic_center";
            

            [luckyItemArray addObject:model];
            
            
        }
        
        
        
        
        
        _viewModel.luckyItemArray = luckyItemArray;
        

    }
    
    return  _viewModel ;
}


II、转盘算法

2.1 旋转到指定下标奖品

  • 旋转到指定下标奖品
代码语言:javascript
复制
/**
 转盘算法
 */
- (void)animationWithSelectonIndex:(NSInteger)index{
    
    [self backToStartPosition];


    
    double perSection  =    M_PI*2/_luckyItemArray.count;
    
    //    //先转4圈 再选区 顺时针(所有这里需要用360-对应的角度) 逆时针不需要

    double toValue= ((M_PI*2 - (perSection*index +perSection*0.5)) + M_PI*2*4);
    
    
    [self RotationWithEndValue: @(toValue - M_PI/2) duration:4 delegate:self];// 因为drawRect从正3点开始画,因此- M_PI/2
        
    
}

- (void)RotationWithEndValue:(id)toValue duration:(CFTimeInterval)duration delegate:(id)delegate{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];

    animation.toValue = toValue;//
    
    animation.duration = duration;
    
    //由快变慢
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//
    animation.delegate = delegate;

    [self.layer addAnimation:animation forKey:@"rotation"];
    
}


  • 恢复起始位置
代码语言:javascript
复制
-(void)backToStartPosition{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    animation.toValue = @(0);
    animation.duration = 0.001;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [self.layer addAnimation:animation forKey:@"rotation"];
}

2.2 处理旋转结束事件

  • CAAnimationDelegate,处理旋转结束事件
代码语言:javascript
复制
#pragma mark - CAAnimationDelegate

- (void)animationDidStart:(CAAnimation *)anim{
    
}

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


    if (self.rotaryEndTurnBlock) {
        self.rotaryEndTurnBlock();
    }

    
}

III、iOS 抽奖轮盘边框动画

https://blog.csdn.net/z929118967/article/details/106238484原理:用NSTimer无限替换UIImageView的Image为互为错位的bg_horse_race_lamp_1或者bg_horse_race_lamp_2,达到跑马灯的效果

  • 应用场景:iOS 抽奖轮盘边框动画

审核注意事项:1、在抽奖页面添加一句文案“本活动与苹果公司无关” 2、在提交审核时修改分级至17+

3.1 实现代码

代码语言:javascript
复制
//
//  ViewController.m
//  horse_race_lamp
//
//  Created by mac on 2021/4/7.
#import <Masonry/Masonry.h>


#import "ViewController.h"
NSString *const bg_horse_race_lamp_1=@"bg_horse_race_lamp_1";
NSString *const bg_horse_race_lamp_2=@"bg_horse_race_lamp_2";

@interface ViewController ()
/**
 
 用NSTimer无限替换bg_horse_race_lamp_1和bg_horse_race_lamp_2,达到跑马灯的效果
 
 应用场景:iOS 抽奖轮盘边框动画
 */
@property (nonatomic,strong) UIImageView *rotaryTable;
@property (nonatomic,strong) NSTimer *itemBordeTImer;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    
    //通过以下两张图片bg_lamp_1 bg_lamp_2,用NSTimer无限替换,达到跑马灯的效果
    _rotaryTable = [UIImageView new];
    _rotaryTable.tag = 100;
    
    [_rotaryTable setImage:[UIImage imageNamed:bg_horse_race_lamp_1]];
    
    [self.view addSubview:_rotaryTable];
    
    [_rotaryTable mas_makeConstraints:^(MASConstraintMaker *make) {
       
        make.center.offset(0);
        
    }];
    
    
    
    _itemBordeTImer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(itemBordeTImerEvent) userInfo:nil repeats:YES];
    
    
    [[NSRunLoop currentRunLoop] addTimer:_itemBordeTImer forMode:NSRunLoopCommonModes];
    
    
    


    
    
}
// 边框动画
- (void)itemBordeTImerEvent
{
    if (_rotaryTable.tag == 100) {
        _rotaryTable.tag = 101;
        [_rotaryTable setImage:[UIImage imageNamed:bg_horse_race_lamp_2]];
    }else if (_rotaryTable.tag == 101){
        _rotaryTable.tag = 100;
        [_rotaryTable setImage:[UIImage imageNamed:bg_horse_race_lamp_1]];
    }
}




@end

3.2 从CSDN下载Demo

从CSDN下载Demo:https://download.csdn.net/download/u011018979/16543761

see also

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS逆向 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • I、根据奖品百分比进行控制中奖概率
    • 1.1 定义奖品模型
      • 1.2 根据奖品的中奖概率获取中奖奖品
        • 1.3 构造数据模型
        • II、转盘算法
          • 2.1 旋转到指定下标奖品
            • 2.2 处理旋转结束事件
            • III、iOS 抽奖轮盘边框动画
              • 3.1 实现代码
                • 3.2 从CSDN下载Demo
                • see also
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档