Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The introduction

Principle: use CoreGraphics for custom turntable drawing

Video: live.csdn.net/v/158749

Download the complete Demo:download.csdn.net/download/u0…

There are two ways to control the winning prizes on the APP side

Method 1: Initiate a network request to obtain the currently selected prize (recommended), that is, the service side controls the winning data, which is more secure

Method two: control the probability of winning according to the percentage of prizes

I. Control the probability of winning according to the percentage of prizes

  • Determine the probabilityRange of random winning according to the probability of winning
  • Determine the winning prizes according to the random winning range

1.1 Define the prize model


#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;
/** The probability of winning the prize */
@property (nonatomic.assign) double probability;

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

/** Win prizes based on the probability of winning prizes */+ (instancetype)getMbyprobabilityRangeWithArr:(NSArray*)arr;

@end

NS_ASSUME_NONNULL_END

Copy the code

1.2 Winning prizes shall be obtained according to the probability of winning prizes

  • Determine the winning prizes according to the random winning range
// Control based on percentage of prizes:
// Title A, index 0, probability80%, that is, when randomNum is 0-80, return the winning index 0
// To make it easier to understand, we called the probabilityRange of prize A 0-80
//

// According to randomNum, determine the winning prize

+ (instancetype)getMbyprobabilityRangeWithArr:(NSArray *)arr {
    
    
    NSInteger randomNum = arc4random()%100;// Control probability

    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% of the time 0-80
            
            
            returnobj; }}return nil;// Thanks for coming

}


Copy the code

1.3 Constructing the data model

  • Determine the probabilityRange of random winning according to the probability of winning
- (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 - the title "",i];
            model.index = i;
            if(i == 1){
                
                model.probability = 0.5;
                
                

            }else{
                model.probability =0.1;

            }
            
            
            // Initialize the realityrange
            probabilityRangeLoc = probabilityRangeLoc +probabilityRangeLen;
            probabilityRangeLen = i+100*model.probability;
            
            
            // The probabilityRange calculation should not include the probability of participation
            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,tex t_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTEwMTg5Nzk=,size_16,color_FFFFFF,t_70#pic_center";
            

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

    }
    
    return  _viewModel ;
}


Copy the code

II. Rotary table algorithm

2.1 Rotate to the specified subscript prize

  • Rotate to the specified subscript prize
/** Turntable algorithm */
- (void)animationWithSelectonIndex:(NSInteger)index{
    
    [self backToStartPosition];


    
    double perSection  =    M_PI*2/_luckyItemArray.count;
    
    // // first turn 4 times and then select clockwise (all here need to use 360- the corresponding Angle) counterclockwise do not need

    double toValue= ((M_PI*2 - (perSection*index +perSection*0.5)) + M_PI*2*4);
    
    
    [self RotationWithEndValue: @(toValue - M_PI/2) duration:4 delegate:self];// Because drawRect starts at plus 3, so -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;
    
    // From fast to slow
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//
    animation.delegate = delegate;

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


Copy the code
  • Restore starting position
- (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"];
}

Copy the code

2.2 Handling the End of rotation Event

  • CAAnimationDelegate, handles the end of rotation event
#pragma mark - CAAnimationDelegate

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

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


    if (self.rotaryEndTurnBlock) {
        self.rotaryEndTurnBlock(); }}Copy the code

III. IOS lottery wheel border animation

Blog.csdn.net/z929118967/… How it works: Replace the UIImageView Image with an NSTimer infinite to either bg_horse_race_lamp_1 or bg_horse_race_lamp_2

  • Application scenario: iOS lottery roulette bezel animation

1. Add a copy of “This activity has nothing to do with Apple” on the lottery page.

2. Revise the grading to 17+ when submitting for review

3.1 Implementation Code

//
// 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(a)
/** Replace bg_horse_race_lamp_1 and bg_horse_race_lamp_2 infinitely with NSTimer
@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.
    
    
    // Use the following two images, bg_lamp_1 bg_lamp_2, with NSTimer infinite replacement, to achieve the effect of running a lantern
    _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];
    
    
    


    
    
}
// Frame animation
- (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:[UIImageimageNamed:bg_horse_race_lamp_1]]; }}@end

Copy the code

3.2 Downloading Demo from the CSDN

From Demo:https://download.csdn.net/download/u011018979/16543761 CSDN download

see also

For more, check out # Applets: iOS Reverse, which presents valuable information only for you, focusing on the mobile technology research field.