Easy Point, which I independently developed, is an app that serves the financial knowledge learning of college students. Logical complex interface, which is the interface to solve the problem, a radio, multiple choice, true or false, short-answer questions, etc., similar to the demo, very few, I also consulted some, learned a lot of experience, write down is worth sharing, this project the first function is relatively simple, so I still use the MVC architecture, we first look at the effect, as shown below:

A brief description of the interface hierarchy implemented: In ViewController, the main ones are: Self. View-> UICollectionView->UITableView of course, there’s UIImageView, UIProgressView, UIButton, those are secondary. First, I used xiB to customize the cell option and created HomePowerExamModel, as shown in the figure below:

Create 3 TableViews, I call them: HomeBaseExamTV, HomeSingleTV, HomeMultiTV, let the next two inherit from the first, let’s look at HomeBaseExamTV code:

#import <UIKit/UIKit.h>@class HomePowerExamModel; @interface HomeBaseExamTV : UITableView<UITableViewDataSource,UITableViewDelegate> @property (nonatomic, strong) HomePowerExamModel * ExModel; @property(nonatomic,strong) NSArray *answerList; @property(nonatomic,strong) NSArray *questionList; @property(nonatomic,copy) NSDictionary *answer; // The default selected answer @property (nonatomic,copy) NSString *tempAnswer; */ - (void)config:(HomePowerExamModel *)model index:(NSInteger)index; @endCopy the code
#import "HomeBaseExamTV.h"
#import "HomePowerExamModel.h"

@interface HomeBaseExamTV()

@end

@implementation HomeBaseExamTV
- (NSArray *)answerList{
    if(! _answerList) { _answerList = @[@"A"The @"B"The @"C"The @"D"The @"E"];
    }
    return _answerList;
}

- (NSArray *)questionList{
    if(! _questionList) { _questionList = @[NONullString(_ExModel.QB_A),NONullString(_ExModel.QB_B),NONullString(_ExModel.QB_C),NONullString(_ExModel.QB_D),NONull String(_ExModel.QB_E)]; }return _questionList;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.separatorStyle = UITableViewCellSeparatorStyleNone;
    }
    returnself; } - (void)config:(HomePowerExamModel *)model index:(NSInteger)index { self.ExModel = model; UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, 0)]; UILabel * titleLb; /* Title text */if (iphoneSE) {
        titleLb = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, self.width-15, 0)];
    } else if (iphone7)
    {
        titleLb = [[UILabel alloc] initWithFrame:CGRectMake(10, 25, self.width-15, 0)];
    } else
    {
        titleLb = [[UILabel alloc] initWithFrame:CGRectMake(10, 35, self.width-20, 0)];
    }
    
    titleLb.numberOfLines = 0;
    titleLb.text = [NSString stringWithFormat:@"% lh-zd, % @",index+1,model.QB_Description];
    if (iphoneSE) {
        titleLb.font = [UIFont systemFontOfSize:14];
    } else
    {
        titleLb.font = [UIFont systemFontOfSize:15];
    }
    [titleLb sizeToFit];
    titleLb.textColor = [UIColor colorWithHexColorString:@"#3c4a55"Alpha: 1.0]; titleLb.textAlignment = NSTextAlignmentNatural; [headerView addSubview:titleLb]; headerView.height = titleLb.bottom + 10; self.tableHeaderView = headerView; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return nil;
}
Copy the code

Next look at the code of HomeSingleTV, because the judgment question is also a single choice, the difference is that the single choice has a maximum of 5 options, only two options, there is a background to return a type judgment question type, so share a tableView, as shown in the following code:

#import "HomeBaseExamTV.h"

@interface HomeSingleTV : HomeBaseExamTV

@end
Copy the code
#import "HomeSingleTV.h"
#import "HomeSelectionCell.h"
#import "HomePowerExamModel.h"

@interface HomeSingleTV()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic, strong) HomePowerExamModel  *model;
@property (nonatomic,strong) NSMutableDictionary  *rowHeightDic;
@property(nonatomic,assign) NSInteger selected;
@end

@implementation HomeSingleTV

- (NSMutableDictionary *)rowHeightDic
{
    if(! _rowHeightDic) { _rowHeightDic = [NSMutableDictionary dictionary]; }return _rowHeightDic;
}

- (NSDictionary *)answer{
    
    if (self.selected != -1)
    {
        return@ {@"QuestionBID":@([self.model.QuestionBId intValue]),@"answer":self.answerList[_selected]};
    } else
    {
         return@ {@"QuestionBID":@([self.model.QuestionBId intValue]),@"answer": @""};
    }
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.selected = -1;
        [self registerNib:[UINib nibWithNibName:@"HomeSelectionCell" bundle:nil] forCellReuseIdentifier:@"HomeSelectionCell"];
        self.backgroundColor = [UIColor clearColor];
        self.bounces = NO;
    }
    returnself; } - (void)config:(HomePowerExamModel *)model index:(NSInteger)index{ [super config:model index:index]; // Call the parent method to set the generic setting self.model = model; self.delegate = self; self.dataSource = self; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {if ([self.model.QB_Type isEqualToString:@"3"]) {
        return 2;
    }
    else
    {
        return self.questionList.count;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    HomeSelectionCell * cell = [tableView dequeueReusableCellWithIdentifier:@"HomeSelectionCell"];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.contentLb.text = [NSString stringWithFormat:@"% @",self.questionList[indexPath.row]];
    cell.contentLb.textColor = [UIColor colorWithHexColorString:@"# 666666"Alpha: 1.0]; cell.contentLb.font = [UIFont systemFontOfSize:14]; cell.backgroundColor = [UIColor clearColor]; NSArray * normalImgName = @[@"A1"The @"B1"The @"C1"The @"D1"The @"E1"];
    NSArray * selectImgName = @[@"A2"The @"B2"The @"C2"The @"D2"The @"E2"];
    [cell.selectBtn setImage:ImageNamed(normalImgName[indexPath.row]) forState:UIControlStateNormal];
    [cell.selectBtn setImage:ImageNamed(selectImgName[indexPath.row]) forState:UIControlStateSelected];
    if ([cell.contentLb.text isEqualToString:@""]) {
        cell.selectBtn.hidden = YES;
    } else
    {
        cell.selectBtn.hidden = NO;
    }
    
    cell.backgroundColor = [UIColor clearColor];
    if (indexPath.row == self.selected)
    {
        cell.selectBtn.selected = YES;
        
    } else
    {
        cell.selectBtn.selected = NO;
    }
    cell.selectBtn.tag = indexPath.row;
    [cell.selectBtn addTarget:self action:@selector(selectBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    CGFloat height = [self getHeightWithStr:cell.contentLb.text];
    if (iphoneSE)
    {
        cell.bgView.frame = CGRectMake(0, 0, 270, height);
        cell.selectBtn.frame = CGRectMake(10, 2, 55, height);
        cell.contentLb.frame = CGRectMake(50, 2, 225, height);
    }
    else if (iphone7)
    {
        cell.bgView.frame = CGRectMake(0, 0, 275, height);
        cell.selectBtn.frame = CGRectMake(10, 2, 55, height);
        cell.contentLb.frame = CGRectMake(50, 2, 225, height);
    }
    else
    {
        cell.bgView.frame = CGRectMake(0, 0, 275, height);
        cell.selectBtn.frame = CGRectMake(15, 2, 55, height);
        cell.contentLb.frame = CGRectMake(50, 2, 225, height);
    }
    returncell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selected = indexPath.row; [self reloadData]; } /* dynamically calculates the cell height based on the returned option text length */ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSNumber *number = [self.rowHeightDic objectForKey:@(indexPath.row).description];if (number) {
        if (iphoneSE) {
            return number.floatValue;
        }
        else
        {
            returnnumber.floatValue + 10; }}else{
        CGFloat height = [self getHeightWithStr:self.questionList[indexPath.row]];
        [self.rowHeightDic setValue:[NSNumber numberWithFloat:height] forKey:@(indexPath.row).description];
        return height;
    }
}

- (CGFloat)getHeightWithStr:(NSString *)str{
    return[self calculateStringHeight:str width:SCREEN_WIDTH - 10 -18 -5 -10 fontSize:17] + 15; } // calculateStringHeight - (CGFloat)calculateStringHeight:(NSString *) STR width:(CGFloat)width fontSize:(CGFloat)size{return[str boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:size]} context:nil].size.height; } /* Save the answer */ - (void)setTempAnswer:(NSString *)tempAnswer{
    if (tempAnswer.length == 0)
        return; _selected = [self.answerList indexOfObject:tempAnswer]; [self reloadData]; } /* select options */ - (void)selectBtnClick:(UIButton *) BTN {self.selected = btn.tag; [self reloadData]; } @endCopy the code

The code of HomeMultiTV is followed by the code of HomeMultiTV. There are many combinations of multiple choice questions, so we need to do two kinds of processing: first, to do a quick sort of multiple choice answers, I am using an array to save the answers, so I do a quick sort of array; When there is no answer submitted, the option can be re – selected, through the button to achieve. The complete code is as follows:

#import "HomeBaseExamTV.h"

@interface HomeMultiTV : HomeBaseExamTV

@end
Copy the code
#import "HomeMultiTV.h"
#import "HomeSelectionCell.h"
#import "HomePowerExamModel.h"

@interface HomeMultiTV ()<UITableViewDelegate,UITableViewDataSource>

@property (nonatomic,strong) NSMutableDictionary *rowHeightDic;
@property(nonatomic,strong) NSMutableArray *selectedArray;
@property (nonatomic, strong) NSArray * multiAnswerList;

@end

@implementation HomeMultiTV
- (NSMutableDictionary *)rowHeightDic{
    if(! _rowHeightDic) { _rowHeightDic = [NSMutableDictionary dictionary]; }return _rowHeightDic;
}

- (NSArray *)multiAnswerList
{
    if(! _multiAnswerList) { _multiAnswerList = @[@"A,"The @"B,"The @"C,"The @"D,"The @"E,"];
    }
    return_multiAnswerList; */ - (NSDictionary *)answer{NSString *answer = @"";
    NSString *Answer = @""; Self.selectedarray sortUsingSelector:@selector(compare:)];for (NSNumber *number in self.selectedArray) {
        Answer =  [Answer stringByAppendingString:self.multiAnswerList[number.intValue]];
    }
    if (Answer.length > 0) {
        answer = [Answer substringToIndex:[Answer length]-1];
    }
    
    if (answer.length>0)
    {
        return@ {@"QuestionBID":@([self.ExModel.QuestionBId intValue]),@"answer":answer};
    } else
    {
        return@ {@"QuestionBID":@([self.ExModel.QuestionBId intValue]),@"answer": @""};
    }
}

- (NSMutableArray *)selectedArray{
    if(! _selectedArray) { _selectedArray = [NSMutableArray array]; }return _selectedArray;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
        [self registerNib:[UINib nibWithNibName:@"HomeSelectionCell" bundle:nil] forCellReuseIdentifier:@"HomeSelectionCell"];
        self.backgroundColor = [UIColor clearColor];
        self.bounces = NO;
    }
    returnself; } - (void)config:(HomePowerExamModel *)model index:(int)index { [super config:model index:index]; self.delegate = self; self.dataSource = self; } /* Save the answer */ - (void)setTempAnswer:(NSString *)tempAnswer{
    
    if (tempAnswer.length == 0)
        return;
    for(int i =0; i < [tempAnswer length]; i++)
    {
        NSString *str = [tempAnswer substringWithRange:NSMakeRange(i, 1)];
        if(! [str isEqualToString:@","]) {
            NSInteger index =  [self.answerList indexOfObject:str];
            if(! [self.selectedArray containsObject:@(index)]) { [self.selectedArray addObject:@(index)]; } } } [self reloadData]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.questionList.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    HomeSelectionCell * cell = [tableView dequeueReusableCellWithIdentifier:@"HomeSelectionCell"];
    cell.contentLb.text = [NSString stringWithFormat:@"% @",self.questionList[indexPath.row]];
    cell.contentLb.font = [UIFont systemFontOfSize:14];
    cell.contentLb.textColor = [UIColor colorWithHexColorString:@"# 666666"Alpha: 1.0]; NSArray * normalImgName = @[@"A1"The @"B1"The @"C1"The @"D1"The @"E1"];
    NSArray * selectImgName = @[@"A2"The @"B2"The @"C2"The @"D2"The @"E2"];
    [cell.selectBtn setImage:ImageNamed(normalImgName[indexPath.row]) forState:UIControlStateNormal];
    [cell.selectBtn setImage:ImageNamed(selectImgName[indexPath.row]) forState:UIControlStateSelected];
    
    if ([cell.contentLb.text isEqualToString:@""]) {
        cell.selectBtn.hidden = YES;
    }
    else
    {
        cell.selectBtn.hidden = NO;
    }
    
    if ([self.selectedArray containsObject:@(indexPath.row)])
    {
        cell.selectBtn.selected = YES;
    } else
    {
        cell.selectBtn.selected = NO;
    }
    cell.backgroundColor = [UIColor clearColor];
    cell.selectBtn.tag = indexPath.row;
    [cell.selectBtn addTarget:self action:@selector(selectBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    CGFloat height = [self _getHeightWithStr:cell.contentLb.text];
    if (iphoneSE)
    {
        cell.bgView.frame = CGRectMake(0, 0, 270, height);
        cell.selectBtn.frame = CGRectMake(10, 2, 55, height);
        cell.contentLb.frame = CGRectMake(50, 2, 225, height);
    }
    else if (iphone7)
    {
        cell.bgView.frame = CGRectMake(0, 0, 275, height);
        cell.selectBtn.frame = CGRectMake(10, 2, 55, height);
        cell.contentLb.frame = CGRectMake(50, 2, 225, height);
    }
    else
    {
        
        cell.bgView.frame = CGRectMake(0, 0, 275, height);
        cell.selectBtn.frame = CGRectMake(15, 2, 55, height);
        cell.contentLb.frame = CGRectMake(50, 2, 225, height);
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self.selectedArray containsObject:@(indexPath.row)]) {
        [self.selectedArray removeObject:@(indexPath.row)];
    }else{ [self.selectedArray addObject:@(indexPath.row)]; } [self reloadData]; } /* dynamic calculation height */ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{NSNumber *number = [self.rowHeightDic objectForKey:@(indexPath.row).description];if (number)
    {
        if (iphoneSE) {
            return number.floatValue;
        }
        else
        {
            returnnumber.floatValue + 10; }}else{
        CGFloat height = [self _getHeightWithStr:self.questionList[indexPath.row]];
        [self.rowHeightDic setValue:
        [NSNumber numberWithFloat:height] forKey:@(indexPath.row).description];
        return height;
    }
}

- (CGFloat)_getHeightWithStr:(NSString *)str{
    return[self calculateStringHeight:str width:SCREEN_WIDTH - 10 -18 -5 -10 fontSize:17] + 15; } // calculateStringHeight - (CGFloat)calculateStringHeight:(NSString *) STR width:(CGFloat)width fontSize:(CGFloat)size{return  [str boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:
NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading 
attributes:
@{NSFontAttributeName:[UIFont systemFontOfSize:size]} context:nil].size.height;
}

- (void)selectBtnClick:(UIButton *)btn
{
    if ([self.selectedArray containsObject:@(btn.tag)]) {
        [self.selectedArray removeObject:@(btn.tag)];
    }
    else
    {
        [self.selectedArray addObject:@(btn.tag)];
    }
    [self reloadData];
}
Copy the code

The model and View code has been implemented. Finally, let’s look at the main code implementation in the Controller. First, create the CollectionView:

- (void)setupCollectionView
{
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
    flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
    flowLayout.minimumInteritemSpacing = 0;
    flowLayout.minimumLineSpacing = 0;
    if (iphoneSE) {
        flowLayout.itemSize = CGSizeMake(260, SCREEN_HEIGHT-64);
    }
    else if (iphone7)
    {
        flowLayout.itemSize = CGSizeMake(306, SCREEN_HEIGHT-64);
    } else{ flowLayout.itemSize = CGSizeMake(337, SCREEN_HEIGHT-64); } // Determine the horizontal slide directionsetScrollDirection:UICollectionViewScrollDirectionHorizontal];
    if (iphoneSE) {
        self.collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64, 260, SCREEN_HEIGHT-150) collectionViewLayout:flowLayout];
        self.collectionView.center = CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
    } else if (iphone7)
    {
        self.collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64, 306, SCREEN_HEIGHT-180) collectionViewLayout:flowLayout];
        self.collectionView.center = CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
    } else
    {
        self.collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64, 337, SCREEN_HEIGHT-200) collectionViewLayout:flowLayout];
        self.collectionView.center = CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
    }
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    self.collectionView.pagingEnabled = YES;
    self.collectionView.scrollEnabled = NO;
    self.collectionView.showsHorizontalScrollIndicator = NO;
    self.collectionView.showsVerticalScrollIndicator = NO;
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"]; self.collectionView.backgroundColor = [UIColor clearColor]; [self.view addSubview:self.collectionView]; / / was first called the self. CollectionView. ContentOffset = CGPointMake (self. CurrentIndex * SCREEN_WIDTH, 0); }Copy the code

Next, implement the proxy method and data source method of the CollectionView:

#pragma mark -- UICollectionViewDataSource,UICollectionViewDelegateFlowLayout
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.dataSource.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath]; [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; self.ExamModel = self.dataSource[indexPath.row]; HomeBaseExamTV * baseTv = nil; // 3if ([self.ExamModel.QB_Type isEqualToString:@"1"])
    {
        baseTv = [[HomeSingleTV alloc] initWithFrame:CGRectZero];
        self.topicTypeLb.text = @"Multiple choice";
    }
    else if ([self.ExamModel.QB_Type isEqualToString:@"2"])
    {
        baseTv = [[HomeMultiTV alloc] initWithFrame:CGRectZero];
        self.topicTypeLb.text = @"Multiple choice";
    }
    else if ([self.ExamModel.QB_Type isEqualToString:@"3"])
    {
        baseTv = [[HomeSingleTV alloc] initWithFrame:CGRectZero];
        self.topicTypeLb.text = @"True or false";
    }
    
    if (iphoneSE) {
        baseTv.frame = CGRectMake(0, 140, 250, self.collectionView.height-64);
    } else if (iphone7)
    {
        baseTv.frame = CGRectMake(0, 170, 306, self.collectionView.height-64);
    } else{ baseTv.frame = CGRectMake(0, 170, 337, self.collectionView.height-64); } [cell.contentView addSubview:baseTv]; /*1 means we did it. Look at the problem */if(self.doneType == 1)
    {
        [baseTv config:self.ExamModel index:indexPath.item];
        baseTv.tempAnswer = self.ExamModel.userAnswer;
    } else
    {
        [baseTv config:self.ExamModel index:indexPath.item];
        baseTv.tempAnswer = self.ExamModel.userAnswer;
    }
    return cell;
}
Copy the code

Since the question making interface can return to the previous question, it is necessary to save the answer to the current question, using the following methods:

/* Save the answer */ - (void)setTempAnswer:(NSString *)tempAnswer{
    if (tempAnswer.length == 0)
        return; _selected = [self.answerList indexOfObject:tempAnswer]; [self reloadData]; } // multiple choice /* save the answer */ - (void)setTempAnswer:(NSString *)tempAnswer{
    
    if (tempAnswer.length == 0)
        return;
    for(int i =0; i < [tempAnswer length]; i++)
    {
        NSString *str = [tempAnswer substringWithRange:NSMakeRange(i, 1)];
        if(! [str isEqualToString:@","]) {
            NSInteger index =  [self.answerList indexOfObject:str];
            if(! [self.selectedArray containsObject:@(index)]) { [self.selectedArray addObject:@(index)]; } } } [self reloadData]; }Copy the code

Here, do the interface is completed, the rest is some logical details of the processing of functions, there are several functions to achieve, I also write down to share, are the most simple and direct way, can be directly used. First, time minute second timing.

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self regularTime]; } - (void)regularTime { __weak typeof(self)weakSelf = self; /* Seconds */ secondValue = 0; The timer = [NSTimer timerWithTimeInterval: 1.0 f block: ^ {[weakSelf timerAction];} repeats: YES]; NSString *str_hour = [NSString stringWithFormat:@"%02d",secondValue/3600];//时
    NSString *str_minute = [NSString stringWithFormat:@"%02d",(secondValue%3600)/60]; NSString *str_second = [NSString stringWithFormat:@"%02d",secondValue%60]; // second NSString *format_time = [NSString stringWithFormat:@"% @ : % @ : % @",str_hour,str_minute,str_second];
    NSLog(@"time:%@",format_time);
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; } - (void)timerAction {/* secondValue++; NSString *str_hour = [NSString stringWithFormat:@"%02d",secondValue/3600];
    NSString *str_minute = [NSString stringWithFormat:@"%02d",(secondValue%3600)/60];
    NSString *str_second = [NSString stringWithFormat:@"%02d",secondValue%60];
    NSString *format_time = [NSString stringWithFormat:@"% @ : % @ : % @",str_hour,str_minute,str_second];
    self.currentTimeLb.text = [NSString stringWithFormat:@"% @",format_time];
}

- (void)dealloc
{
    NSLog(@"%s",__func__);
}
Copy the code

** Second, prevent violence click. ** click “Confirm” button to submit the answer, in order to prevent users from violent clicking, so click interval less than 1 second, invalid.

- (IBAction)submitBtnClick:(UIButton *)btn
{
    DLog(@" %s ",__FUNCTION__); [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(handleEvent:) object:btn]; [the self performSelector: @ the selector (handleEvent) withObject: BTN afterDelay: 1.0]; } - (void)handleEvent:(UIButton *)btn {}Copy the code

** Third, get the answer to the current question. ** When I click ok to submit, SAVE the answer to the current question and then slide to the next question. When I slide back to the previous question, I can still show the answer to the previous question. Self. currentIndex is the page number of the current question.

#pragma mark - scrollViewDelegate- (void)scrollViewDidScroll:(UIScrollView *)scrollView { NSInteger index = (scrollView. ContentOffset. X + scrollView. Frame. The size, width * 0.5)/scrollView frame. The size. The width;if(index ! = self. CurrentIndex | | index = = self. DefautIndex) {/ / page changed / / here is set to 1 for the index = = self. The self defautIndex failure. DefautIndex = - 1; [self updateAnswers]; self.currentIndex = index; DLog(@"index:%zd",index); }}#pragma mark updates the temporary answers
- (void)updateAnswers{
    
    for (UICollectionViewCell *cell in [self.collectionView visibleCells]) {
        
        HomeBaseExamTV *tableView = cell.contentView.subviews[0];
        
        [self.dataSource enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(HomePowerExamModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
            
            if (model.QuestionBId == [NSString stringWithFormat:@"% @",tableView.answer[@"QuestionBID"]] ) {
                model.userAnswer = tableView.answer[@"answer"];
                if ([model.QB_Type isEqualToString:@"3"] && ![model.userAnswer isEqualToString:@""]) {
                    if ([model.userAnswer isEqualToString:@"A"]) {
                        model.userAnswer = @"To";
                    } else
                    {
                        model.userAnswer = @"Wrong";
                    }
                }
                DLog(@"Answer: %@",model.userAnswer);
                if (self.currentIndex == self.dataSource.count-1)
                {
                    [self submitData:model.userAnswer Type:@"1"];
                } else
                {
                    [self submitData:model.userAnswer Type:@"0"]; }}}]; }}Copy the code
- (NSDictionary *)answer{if (self.selected != -1)
    {
        return@ {@"QuestionBID":@([self.model.QuestionBId intValue]),@"answer":self.answerList[_selected]};
    } else
    {
         return@ {@"QuestionBID":@([self.model.QuestionBId intValue]),@"answer": @""}; (NSDictionary *)answer{NSString *answer = @"";
    NSString *Answer = @""; Self.selectedarray sortUsingSelector:@selector(compare:)];for (NSNumber *number in self.selectedArray) {
        Answer =  [Answer stringByAppendingString:self.multiAnswerList[number.intValue]];
    }
    if (Answer.length > 0) {
        answer = [Answer substringToIndex:[Answer length]-1];
    }
    
    if (answer.length>0)
    {
        return@ {@"QuestionBID":@([self.ExModel.QuestionBId intValue]),@"answer":answer};
    } else
    {
        return@ {@"QuestionBID":@([self.ExModel.QuestionBId intValue]),@"answer": @""}; }}Copy the code
conclusion

App project business development, more is involved interactive logic design, there will be a lot of details, these are the experience, the app developers, in the process of implementation will have a lot of bugs, but stepping over is the experience of ascension, record, in addition to share, is also for your review, hope you can improve, come on together.