iOS開發(fā) ? 實例——用CollectionView和tableView實現(xiàn)做題界面功能

上個月润努,我獨立開發(fā)的 融易點 已成功上架了关斜,是一款為高校學(xué)生金融知識學(xué)習(xí)做服務(wù)的app,目前是1.0版本铺浇。那里面邏輯比較復(fù)雜的界面蚤吹,就是做題界面,有單選随抠、多選題、判斷題繁涂、簡答題等等拱她,類似的demo,很少扔罪,我也參考了一些秉沼,學(xué)到了不少經(jīng)驗,值得寫下來分享矿酵,這個項目第一版功能相對簡單唬复,所以我還是采用了MVC的架構(gòu),我們先看看效果全肮,如下所示:

1.gif

簡單說說實現(xiàn)的界面層次結(jié)構(gòu):
ViewController中敞咧,主要的有:self.view->UICollectionView->UITableView
當(dāng)然了,界面上還有UIImageView辜腺、UIProgressView休建、UIButton,這些是次要的评疗。
接下來测砂,開始具體的實現(xiàn)過程,首先百匆,自定義選項的cell砌些,我使用的是xib,同時創(chuàng)建HomePowerExamModel加匈,如圖所示:

image.png
image.png
image.png

創(chuàng)建3個tableView存璃,我把他們命名為:HomeBaseExamTV仑荐,HomeSingleTV,HomeMultiTV有巧,讓后面兩個繼承于第一個释漆,先看看HomeBaseExamTV的代碼:

#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;
//  默認(rèn)選中的答案
@property (nonatomic,copy) NSString *tempAnswer;

/**
 通用設(shè)置  子類實現(xiàn)必須調(diào)用super
 @param model      數(shù)據(jù)模型
 @param index      第幾題
 */
- (void)config:(HomePowerExamModel *)model index:(NSInteger)index;
@end
#import "HomeBaseExamTV.h"
#import "HomePowerExamModel.h"

@interface HomeBaseExamTV()

@end

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

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

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.separatorStyle = UITableViewCellSeparatorStyleNone;
    }
    return self;
}

- (void)config:(HomePowerExamModel *)model index:(NSInteger)index
{
    self.ExModel = model;
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, 0)];
    UILabel * titleLb;
    /*題目文字*/
    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:@"%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;
}

接下來看看HomeSingleTV的代碼篮迎,由于判斷題也屬于單選題男图,不一樣的是,單選題最多有5個選項甜橱,判斷題只有兩個選項逊笆,后臺有返回一個type判斷題型,所以共用一個tableView岂傲,如下代碼所示:

#import "HomeBaseExamTV.h"

@interface HomeSingleTV : HomeBaseExamTV

@end
#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;
    }
    return self;
}

- (void)config:(HomePowerExamModel *)model index:(NSInteger)index{
    [super config:model index:index];//調(diào)用父類方法  設(shè)置通用設(shè)置
    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",@"B1",@"C1",@"D1",@"E1"];
    NSArray * selectImgName = @[@"A2",@"B2",@"C2",@"D2",@"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);
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.selected = indexPath.row;
    [self reloadData];
}

/*根據(jù)返回的選項文字長度動態(tài)計算cell高度*/
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSNumber *number = [self.rowHeightDic objectForKey:@(indexPath.row).description];
    if (number) {
        if (iphoneSE) {
            return number.floatValue;
        }
        else
        {
            return number.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;
}

//  計算文字高度
- (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)setTempAnswer:(NSString *)tempAnswer{
    if (tempAnswer.length == 0)
        return;
    _selected = [self.answerList indexOfObject:tempAnswer];
    [self reloadData];
}

/*單選點擊選項*/
- (void)selectBtnClick:(UIButton *)btn
{
    self.selected = btn.tag;
    [self reloadData];
}
@end

接著是HomeMultiTV的代碼难裆,多選題由于有多種組合,所以需要做兩種處理:一镊掖、對多選題答案進行快速排序乃戈,我是用數(shù)組來保存答案,所以對數(shù)組進行快速排序亩进;
二症虑、多選題在沒有提交答案的時候,選項是可以重新選归薛,通過按鈕來實現(xiàn)谍憔。

完整代碼如下:

#import "HomeBaseExamTV.h"

@interface HomeMultiTV : HomeBaseExamTV

@end
#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,",@"B,",@"C,",@"D,",@"E,"];
    }
    return _multiAnswerList;
}

/*后臺對多選題的答案要求按照ABCDE這樣的順序,所以進行排序*/
- (NSDictionary *)answer{
    
    NSString *answer = @"";
    NSString *Answer = @"";
    /*給數(shù)組快速排序*/
    [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;
    }
    return self;
}

- (void)config:(HomePowerExamModel *)model index:(int)index
{
    [super config:model index:index];
    self.delegate = self;
    self.dataSource = self;
}

/*保存答案*/
- (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",@"B1",@"C1",@"D1",@"E1"];
    NSArray * selectImgName = @[@"A2",@"B2",@"C2",@"D2",@"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];
}

/*動態(tài)計算高度*/
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSNumber *number = [self.rowHeightDic objectForKey:@(indexPath.row).description];
    
    if (number)
    {
        if (iphoneSE) {
            return number.floatValue;
        }
        else
        {
            return number.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;
}

//  計算文字高度
- (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];
}

model和 View的代碼已經(jīng)實現(xiàn)主籍,最后习贫,看看Controller中的主要代碼實現(xiàn),首先千元,創(chuàng)建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);
    }
    
    //確定水平滑動方向
    [flowLayout setScrollDirection: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];
    // 首次調(diào)用
    self.collectionView.contentOffset = CGPointMake(self.currentIndex*SCREEN_WIDTH, 0);
}

緊接著苫昌,實現(xiàn)CollectionView的代理方法和數(shù)據(jù)源方法:

#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;
    //題型 1單選 2多選 3判斷
    if ([self.ExamModel.QB_Type isEqualToString:@"1"])
    {
        baseTv = [[HomeSingleTV alloc] initWithFrame:CGRectZero];
        self.topicTypeLb.text = @"單選題";
    }
    else if ([self.ExamModel.QB_Type isEqualToString:@"2"])
    {
        baseTv = [[HomeMultiTV alloc] initWithFrame:CGRectZero];
        self.topicTypeLb.text = @"多選題";
    }
    else if ([self.ExamModel.QB_Type isEqualToString:@"3"])
    {
        baseTv = [[HomeSingleTV alloc] initWithFrame:CGRectZero];
        self.topicTypeLb.text = @"判斷題";
    }
    
    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表示做過了,看題目*/
    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;
}

由于做題界面是可以返回上一道題的诅炉,所以需要保存當(dāng)前題目的答案蜡歹,用到的方法如下:

//單選題
/*保存已答過的答案*/
- (void)setTempAnswer:(NSString *)tempAnswer{
    if (tempAnswer.length == 0)
        return;
    _selected = [self.answerList indexOfObject:tempAnswer];
    [self reloadData];
}

//多選題
/*保存答案*/
- (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];
}

到這里,做題界面就完成了涕烧,剩下的就是一些邏輯細節(jié)功能的處理月而,有幾個功能實現(xiàn),我也寫下來分享议纯,都是最簡單直接的方式父款,可以直接用。
第一、時分秒計時憨攒。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self regularTime];
}

- (void)regularTime
{
    __weak typeof(self)weakSelf = self;
    /*計時秒數(shù)*/
    secondValue = 0;
    timer = [NSTimer timerWithTimeInterval:1.0f 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];//秒
    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__);
}

第二世杀、防止暴力點擊。點確定按鈕提交答案時肝集,為了防止用戶暴力點擊瞻坝,所以,點擊間隔時間小于1秒的杏瞻,無效所刀。

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

- (void)handleEvent:(UIButton *)btn
{}

第三、獲取當(dāng)前題目答案捞挥。點擊確認(rèn)提交答案的同時浮创,保存當(dāng)前題目答案,然后滑動到下一題砌函,我再滑回上一道題的時候斩披,依然可以展示上一道題的答案,self.currentIndex是指當(dāng)前題目的頁碼讹俊。

#pragma mark - scrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSInteger index = (scrollView.contentOffset.x+scrollView.frame.size.width*0.5)/scrollView.frame.size.width;
    if (index != self.currentIndex || index == self.defautIndex) {//頁面改變了
        // 這里設(shè)置成-1  為了index == self.defautIndex 失效
        self.defautIndex = -1;
        
        [self updateAnswers];
        
        self.currentIndex = index;
        DLog(@"index:%zd",index);
    }
}

#pragma mark 更新暫存的答案
- (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 = @"對";
                    } else
                    {
                        model.userAnswer = @"錯";
                    }
                }
                DLog(@"答案:%@",model.userAnswer);
                if (self.currentIndex == self.dataSource.count-1)
                {
                    [self submitData:model.userAnswer Type:@"1"];
                } else
                {
                    [self submitData:model.userAnswer Type:@"0"];
                }
            }
        }];
    }
}
//如果是單選題垦沉,則對應(yīng)的是這個方法
- (NSDictionary *)answer{
    
    if (self.selected != -1)
    {
        return  @{@"QuestionBID":@([self.model.QuestionBId intValue]),@"answer":self.answerList[_selected]};
    } else
    {
         return @{@"QuestionBID":@([self.model.QuestionBId intValue]),@"answer":@""};
    }
}

//如果是多選題,那answer對應(yīng)的方法就是快速排序仍劈,就是前面MultiTV中的方法
- (NSDictionary *)answer{
    
    NSString *answer = @"";
    NSString *Answer = @"";
    /*給數(shù)組快速排序*/
    [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":@""};
    }
}
總結(jié)

app項目業(yè)務(wù)開發(fā)乡话,更多是涉及到交互邏輯設(shè)計,會有很多細節(jié)耳奕,這些都是經(jīng)驗,對app開發(fā)人員來說诬像,在實現(xiàn)的過程中會遇到很多bug屋群,但踩過來了就是經(jīng)驗的提升,記錄下來坏挠,除了分享芍躏,也是對自己的回顧,希望自己能夠不斷提升降狠,一起加油对竣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市榜配,隨后出現(xiàn)的幾起案子否纬,更是在濱河造成了極大的恐慌,老刑警劉巖蛋褥,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件临燃,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機膜廊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門乏沸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人爪瓜,你說我怎么就攤上這事蹬跃。” “怎么了铆铆?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵蝶缀,是天一觀的道長。 經(jīng)常有香客問我算灸,道長扼劈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任菲驴,我火速辦了婚禮荐吵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赊瞬。我一直安慰自己先煎,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布巧涧。 她就那樣靜靜地躺著薯蝎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谤绳。 梳的紋絲不亂的頭發(fā)上占锯,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音缩筛,去河邊找鬼消略。 笑死,一個胖子當(dāng)著我的面吹牛瞎抛,可吹牛的內(nèi)容都是我干的艺演。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼桐臊,長吁一口氣:“原來是場噩夢啊……” “哼胎撤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起断凶,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤伤提,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后认烁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體飘弧,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡识藤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了次伶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痴昧。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖冠王,靈堂內(nèi)的尸體忽然破棺而出赶撰,到底是詐尸還是另有隱情,我是刑警寧澤柱彻,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布豪娜,位于F島的核電站,受9級特大地震影響哟楷,放射性物質(zhì)發(fā)生泄漏瘤载。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一卖擅、第九天 我趴在偏房一處隱蔽的房頂上張望鸣奔。 院中可真熱鬧,春花似錦惩阶、人聲如沸挎狸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锨匆。三九已至,卻和暖如春冬筒,著一層夾襖步出監(jiān)牢的瞬間恐锣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工舞痰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留侥蒙,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓匀奏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親学搜。 傳聞我的和親對象是個殘疾皇子娃善,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,498評論 25 707
  • 早晨下車你跟我說中午見,因為中午媽媽要和你們一起去生態(tài)園春游瑞佩,這還是我第一次和你們?nèi)ゴ河巍?在生態(tài)園里你們都很開心...
    萍萍淡淡閱讀 168評論 0 0
  • 誰的父親死了蜒蕾,請你告訴我如何悲傷。誰的愛人走了焕阿,請你告訴我如何遺忘咪啡。我們生來就是孤獨,我們生來就是孤單暮屡。 ...
    鄰家阿七閱讀 721評論 0 4
  • 昨晚輾轉(zhuǎn)難眠撤摸,無法入睡“伲或許是激動准夷,或許摻雜著緊張,又或許是開心莺掠,心情反復(fù)變化著衫嵌,只是因為我即將面對一位非常重要的...
    Mook的那些年閱讀 379評論 0 2