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

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

引言

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

视频:live.csdn.net/v/158749

下载完整Demo:download.csdn.net/download/u0…

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

方式一: 发起网络请求获取当前选中奖品(推荐),即由服务侧控制中奖数据,更安全

方式二:根据奖品百分比进行控制中奖概率

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

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

在这里插入图片描述

1.1 定义奖品模型


#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,确定中奖奖品
// 根据奖品百分比进行控制:
// 奖品 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
- (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 旋转到指定下标奖品

  • 旋转到指定下标奖品
/**
 转盘算法
 */
- (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"];
    
}


复制代码
  • 恢复起始位置
-(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,处理旋转结束事件
#pragma mark - CAAnimationDelegate

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

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


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

    
}

复制代码

III、iOS 抽奖轮盘边框动画

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

在这里插入图片描述

在这里插入图片描述

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

审核注意事项: 1、在抽奖页面添加一句文案“本活动与苹果公司无关”

2、在提交审核时修改分级至17+

3.1 实现代码

//
//  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

更多内容请关注#小程序:iOS逆向,只为你呈现有价值的信息,专注于移动端技术研究领域。

猜你喜欢

转载自juejin.im/post/7017695429299175461