实现的效果是:
1.点击答案,判断正确,如果选择的答案错误显示出正确的答案。然后可以浏览上一题的信息。
2.可以查看上一题的答题情况。
看下效果图吧
思路:
1.看看题的模型吧,我这里是用一个数组来装的一个类,然后点击下一题的时候数组索引+1,上一题的数组模型-1,用户选择的答案和正确答案都存在数组里面的类中。
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里面放一个按钮,在用户做出选择之后改变按钮的图片(✅或者❌)。 数据返回两组一组显示题和答案,一组显示上一题和下一题。
//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
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.检查答案是否正确
//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.上一题和下一题就直接模型数组的索引进行加减,然后对边界做一下简单的判断处理就行了。
//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()
}
复制代码
6.所有代码
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
}
}
}
复制代码