实现的效果是:

1.点击答案,判断正确,如果选择的答案错误显示出正确的答案。然后可以浏览上一题的信息。

2.可以查看上一题的答题情况。

看下效果图吧

思路:

1.看看题的模型吧,我这里是用一个数组来装的一个类,然后点击下一题的时候数组索引+1,上一题的数组模型-1,用户选择的答案和正确答案都存在数组里面的类中。

1
2
3
4
5
6
7
8
9
10
11
12
13
class OnlineTestDetailModel: HandyJSON {
/** 题的ID */
var id:String?
/** 问题 */
var question:String?
/** 答案选项 */
var answers:[String]?
//正确答案索引
var right:String?
/** 当前选择的答案 */
var choose_answer:Int?
required init() {}
}

2.整个是用的tableView来做的。问题是一种cell,答案是一种cell,然后cell里面放一个按钮,在用户做出选择之后改变按钮的图片(✅或者❌)。

数据返回两组一组显示题和答案,一组显示上一题和下一题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//MARK:-----------注册cell-------------//
func registCell(){
/** 问题cell */
tableView.register(UINib(nibName:"OnlineTestDetailCell",bundle:nil), forCellReuseIdentifier: "cell")
/** 上一题和下一题cell */
tableView.register(UINib(nibName:"LastAndNextCell",bundle:nil), forCellReuseIdentifier: "cell2")
/** 答案选项cell */
tableView.register(UINib(nibName:"OnlineAnswerCell",bundle:nil), forCellReuseIdentifier: "cell3")
}

func numberOfSections(in tableView: UITableView) -> Int {
return 2
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
if self.arrayData.count != 0 {
let model = self.arrayData[answerIndex]
let count = model.answers?.count ?? 0
//这里+1是加了题目的数量
return count + 1
}
return 0
}
//否则就返回上一题和下一题的cell数量
return 1
}

3.用户点击答案cell的时候就判断是否正确然后改变按钮的image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

/** 如果用户已经选择过答案了 */
let model = self.arrayData[answerIndex]
if model.choose_answer != nil { return }
/** 如果用户没有选择答案 */
if let cell = tableView.cellForRow(at: indexPath) as? OnlineAnswerCell{
self.choose_answer = indexPath.row
/** current_cell 是用来判断用户是否选择了答案如果没有选择答案,就为nil */
self.current_cell = cell
check_answer()
}else{
self.current_cell = nil
}

}

4.检查答案是否正确

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//MARK:-----------判断用户选择是否正确-------------//
func check_answer(){
/** 判断用户是否选择了答案 */
if current_cell == nil { return }
let model = self.arrayData[answerIndex]
/** 记录用户选择的答案 */
model.choose_answer = choose_answer
let right = Int(model.right ?? "0")!
if model.choose_answer == right{
/** 如果选择了对的答案 */
let cell = tableView.cellForRow(at: IndexPath(row: model.choose_answer!, section: 0)) as? OnlineAnswerCell
cell?.labelAnswer.setImage(UIImage(named:"对勾"), for: .normal)
}else{
/** 如果选择了错误的答案 */
let cell = tableView.cellForRow(at: IndexPath(row: model.choose_answer!, section: 0)) as? OnlineAnswerCell
cell?.labelAnswer.setImage(UIImage(named:"错"), for: .normal)
let cell2 = tableView.cellForRow(at: IndexPath(row: right, section: 0)) as? OnlineAnswerCell
cell2?.labelAnswer.setImage(UIImage(named:"对勾"), for: .normal)
}

//如果选择到了最后一道题就显示交卷按钮
finish_changeBtn()
}

5.上一题和下一题就直接模型数组的索引进行加减,然后对边界做一下简单的判断处理就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//MARK:-----------下一题-------------//
@objc func btn_next_action(sender:UIButton){

//交卷
if sender.titleLabel?.text == "完成交卷" { request_submit_finish();return }

/** 如果没有选择答案就不做处理 */
let model = self.arrayData[answerIndex]
if model.choose_answer == nil { return }

if answerIndex + 1 >= self.arrayData.count { return }
answerIndex = answerIndex + 1
self.tableView.reloadData()
}
//MARK:-----------上一题-------------//
@objc func btn_last_action(){

if answerIndex - 1 < 0 { return }
answerIndex = answerIndex - 1
self.tableView.reloadData()

}

全部代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
class OnlineTestDetailVC: CommentTableViewVC {

var currentAnwserCell:OnlineTestDetailCell!

var arrayData:[OnlineTestDetailModel] = []

/** 判断是第几道题的 */
private var answerIndex:Int = 0

/** 选择的是第几道题 */
private var choose_answer:Int = 0

/** 当前选择的cell */
private var current_cell:OnlineAnswerCell?

/** 答题分类的id */
var questionID:Int = 0

override func viewDidLoad() {
super.viewDidLoad()

self.navigationItem.title = "在线测试"
tableView.delegate = self
tableView.dataSource = self
tableView.mj_header = nil
//MARK:-----------注册cell-------------//
registCell()
//请求每一道题
request_question_list()
}

//MARK:-----------请求每一道题-------------//
func request_question_list(){
showStaus("正在请求...")
NetworkTool.requestData(urlString: api_start_testing,params: ["classify":questionID], method: .post) { (res) in
if let model = OnlineTestArrayDetailModel.deserialize(from: res){
guard let array = model.data else { return }
self.arrayData = array
self.tableView.reloadData()
}
}
}

//MARK:-----------注册cell-------------//
func registCell(){
/** 问题cell */
tableView.register(UINib(nibName:"OnlineTestDetailCell",bundle:nil), forCellReuseIdentifier: "cell")
/** 上一题和下一题cell */
tableView.register(UINib(nibName:"LastAndNextCell",bundle:nil), forCellReuseIdentifier: "cell2")
/** 答案选项cell */
tableView.register(UINib(nibName:"OnlineAnswerCell",bundle:nil), forCellReuseIdentifier: "cell3")
}

//MARK:-----------交卷请求-------------//
func request_submit_finish(){
showStaus("请稍后...")

let qIDs = self.arrayData.flatMap{ $0.id }
let answers = self.arrayData.flatMap{ $0.choose_answer }

NetworkTool.requestData(urlString: api_submit_an_answer,params: ["uid":UserMananager.manager.uid ?? "","question":qIDs,"answer":answers,"classify":questionID], method: .post) { (res) in
if let code = res["code"] as? Int{
if code == 200 {
if let model = OnlineTestRecordModel.deserialize(from: res["info"] as? [String:Any]){
let vc = OnlineTestRecordDetailVC()
vc.answerModel = model
vc.arrayQuestionData = self.arrayData
self.push_vc(sender: vc)
}
}
}
}
}

//MARK:-----------下一题-------------//
@objc func btn_next_action(sender:UIButton){

//交卷
if sender.titleLabel?.text == "完成交卷" { request_submit_finish();return }

/** 如果没有选择答案就不做处理 */
let model = self.arrayData[answerIndex]
if model.choose_answer == nil { return }

if answerIndex + 1 >= self.arrayData.count { return }
answerIndex = answerIndex + 1
self.tableView.reloadData()
}
//MARK:-----------上一题-------------//
@objc func btn_last_action(){

if answerIndex - 1 < 0 { return }
answerIndex = answerIndex - 1
self.tableView.reloadData()

}

//MARK:-----------判断用户选择是否正确-------------//
func check_answer(){
/** 判断用户是否选择了答案 */
if current_cell == nil { return }
let model = self.arrayData[answerIndex]
/** 记录用户选择的答案 */
model.choose_answer = choose_answer
let right = Int(model.right ?? "0")!
if model.choose_answer == right{
/** 如果选择了对的答案 */
let cell = tableView.cellForRow(at: IndexPath(row: model.choose_answer!, section: 0)) as? OnlineAnswerCell
cell?.labelAnswer.setImage(UIImage(named:"对勾"), for: .normal)
}else{
/** 如果选择了错误的答案 */
let cell = tableView.cellForRow(at: IndexPath(row: model.choose_answer!, section: 0)) as? OnlineAnswerCell
cell?.labelAnswer.setImage(UIImage(named:"错"), for: .normal)
let cell2 = tableView.cellForRow(at: IndexPath(row: right, section: 0)) as? OnlineAnswerCell
cell2?.labelAnswer.setImage(UIImage(named:"对勾"), for: .normal)
}

//如果选择到了最后一道题就显示交卷按钮
finish_changeBtn()
}

//MARK:-----------完成交卷-------------//
func finish_changeBtn(){
//MARK:-----------如果用户做到了最后一题,就显示提交试卷-------------//
if let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 1)) as? LastAndNextCell, answerIndex + 1 >= self.arrayData.count{
cell.btnlast.isHidden = true
cell.btnNext.snp.remakeConstraints({ (make) in
make.width.equalTo(150)
make.height.equalTo(50)
make.top.equalTo(50)
make.centerX.equalToSuperview()
})
cell.btnNext.setTitle("完成交卷", for: .normal)
}
}
}

extension OnlineTestDetailVC:UITableViewDelegate,UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
if self.arrayData.count != 0 {
let model = self.arrayData[answerIndex]
let count = model.answers?.count ?? 0
return count + 1
}
return 0
}
return 1
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 1 { return 300 }
if indexPath.row == 0 {
let model = self.arrayData[answerIndex]
let text = model.question ?? ""
return text.get_heightForComment(fontSize: fontMid, width: SCREEN_WIDTH - 40) + 80
}else{
return 60
}
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 1{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2") as? LastAndNextCell
cell?.btnlast.addTarget(self, action: #selector(btn_last_action), for: .touchUpInside)
cell?.btnNext.addTarget(self, action: #selector(btn_next_action(sender:)), for: .touchUpInside)
return cell!
}else{
//MARK:-----------问题模型-------------//
let model = self.arrayData[answerIndex]
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? OnlineTestDetailCell
cell?.model = model
/** 第几道题 */
cell?.labelIndex.text = "第\(answerIndex+1)题"
return cell!
}
//MARK:-----------答案记录-------------//
let cell = tableView.dequeueReusableCell(withIdentifier: "cell3") as? OnlineAnswerCell
cell?.labelAnswer.setTitle(" \(model.answers![indexPath.row - 1])", for: .normal)
//MARK:-----------如果用户点击上一题,或者下一题需要刷新选择的题-------------//
if model.choose_answer == nil {
/** 如果其他题没有选择就隐藏对错的图片 */
cell?.labelAnswer.setImage(nil, for: .normal)
}else{
/** 获取正确的答案 */
let right = Int(model.right ?? "0")!
if indexPath.row == right{
/** 如果选择了对的答案 */
cell?.labelAnswer.setImage(UIImage(named:"对勾"), for: .normal)
}else if indexPath.row == model.choose_answer{
cell?.labelAnswer.setImage(UIImage(named:"错"), for: .normal)
}else{
cell?.labelAnswer.setImage(nil, for: .normal)
}

}

return cell!
}

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

/** 如果用户已经选择过答案了 */
let model = self.arrayData[answerIndex]
if model.choose_answer != nil { return }
/** 如果用户没有选择答案 */
if let cell = tableView.cellForRow(at: indexPath) as? OnlineAnswerCell{
self.choose_answer = indexPath.row
/** current_cell 是用来判断用户是否选择了答案如果没有选择答案,就为nil */
self.current_cell = cell
check_answer()
}else{
self.current_cell = nil
}

}

}
相关文章
评论
分享
  • 删除视频背景音乐、添加视频背景音乐

    删除视频背景音乐删除视频的背景音乐其实很简单,把视频数据导入进来,然后我们的视频数据其实是有两条轨道一条是音频,另外一条是视频。由于数据的tracks(轨道包含多条音视频)是只读的,所以在这里重新创建一个混合器,然后把数据源的视频轨道...

    删除视频背景音乐、添加视频背景音乐
  • AAC音频转WAV

    将aac编码格式的音频转为lpcm编码的音频,转出来的音频会比原来大个10倍左右.1234567891011121314151617181920212223242526272829303132333435363738394041424...

    AAC音频转WAV
  • Message Filtter Extension 短信过滤

    手机最近老是收到各种垃圾短信,于是想要自己写一个app来过滤垃圾短信,找到了Message Filtter Extension 1.首先创建一个空的工程,然后创建好了之后添加一个target。1选中工程->Editor-&g...

    Message Filtter Extension 短信过滤
  • Shell删除所有苹果证书

    123456789101112131415161718#!/bin/bashexpired=$(security find-identity)if [ -z "$expired" ] #-z判断字符串长度是否为0 为0返回tru...

    Shell删除所有苹果证书
  • Swift语言国际化

    第一步在工程设置里面添加对应国际化的语言 第二步添加Localizble.strings 第三步选择Localizble.strings文件,然后选择Localize…选择需要的语言,选择完了之后你就会看见刚才创建的Localizbl...

    Swift语言国际化
  • Docker Nginx 静态资源部署

    1. 查看docker仓库中的nginx命令1docker search nginx 2.为选定需要pull到系统重的官方Nginx镜像1docker pull nginx 这个过程需要时间,需要耐心等待一下。看到这个图就是成功了。 ...

    Docker Nginx 静态资源部署
  • Nginx vue打包部署

    最近在弄vue的项目,完了需要打包部署到服务器,然后之前也没有弄过自己在这边一边查资料一边琢磨怎么弄。幸运的是花了一天半的时间还搞定了。 1.在conf.d文件下添加一个新的配置文件,12345678910111213141516...

    Nginx vue打包部署
  • SCP文件上传下载

    从服务器获取文件1scp -p 8080 root@192.168.1.1:/usr/temp/file.txt /Desktop/ 上传文件到服务器1scp -p 8080 /Desktop/uploadfile root@192....

    SCP文件上传下载
  • 音频剪切、合成、淡入淡出

    音频剪切1.音频剪切比较简单传入音频文件和剪切的时间段就可以了12345678910111213141516171819202122232425/** 初始化输出文件路径 */ NSString *url = "音频源文件路径"...

    音频剪切、合成、淡入淡出
  • iOS原生调用ReatNative

    有一个RN的项目其中一个即时通讯的模块需要用原生来写所以这里面就涉及到iOS原生和RN的交互。 iOS调用RN1.创建一个交互通信的类。1234#import <React/RCTEventEmitter.h>#imp...

    iOS原生调用ReatNative