一、来,理理思路、理理思路,咱们看看上节课做到哪儿了 上节课是不是做到这儿了,一点待选项按钮,能上来吧,上面填满了以后,下面不能点了吧,上面的一点,可以下来吧,最后我们发现,给每一个optionButton,加一个Tag,这样点上去,让这个答案按钮的Tag和它一样,是不是这两个就可以一一匹配了,当你在点击答案按钮的时候,找到这个option按钮中和它相同的Tag,让它显示出来,是不是就OK了, 2.来,接下来,我们要做的就是,当你点击option按钮,把这个答案按钮填满以后,做一个判断,如果这个答案是对的,就让文字的颜色变成蓝色,然后呢,0.5秒钟之后呢,跳转到下一题, 如果文字、如果答案是错的,就让文字显示成红色,是不是判断一下答案是否正确吧, 请问大家,这个判断答案是否正确,应该写在哪里呢,肯定是控制器里面,这个不用你说,问的是控制器的哪个地方,答案按钮的点击事件、还是这个待选项按钮的点击事件吧, 对,还是这个待选按钮的单击事件吧,当你每次点一个待选按钮,都要做一个判断吗,每次点一个都要做一个判断,所以说找到我们待选按钮的单击事件,optionButtonClick事件吧 - (void)optionButtonClick:(UIButton *)sender{ //1.隐藏当前被点击的待选按钮 sender.hidden = YES; //2.把当前被点击的按钮的文字显示到第一个为空的答案按钮上 NSString *text = sender.currentTitle; //3 把文字显示到答案按钮上 //遍历每一个答案按钮 for(UIButton *answerBtn in self.answerView.subviews){ //判断每个答案按钮上的文字是否为nil if(answerBtn.currentTitle == nil){ //把当前点击的待选按钮的文字设置给对应的答案按钮 [answerBtn setTitle:text forState:UIControlStateNormal]; //把当前点击的待选按钮的tag值也设置给对应的答案按钮 answerBtn.tag = sender.tag; break; } } //4.判断答案按钮是否已经填满了 //一开始假设答案按钮是填满的 BOOL isFull = YES; for(UIButton *btnAnswer in self.answerView.subviews){ if(btnAnswer.currentTitle == nil){ isFull = NO; break; } } //如果已经填满了,则禁止option view 控件与用户的交互 if(isFull){ //禁止待选按钮被点击 self.optionsView.userInteractionEnabled = NO; } } 在这个待选按钮的单击事件里面,我们: 1)第一,让被点击的待选按钮隐藏 2)第二,获取当前被点击的待选按钮上的文字 3)第三,在答案按钮中找第一个为空的答案按钮,把待选按钮的文字写上去,同时把待选按钮的Tag,设置给答案按钮的Tag,然后break 4)第四,判断当前答案按钮是否填满了,如果填满了,是不是禁止待选按钮被点击啊 5)第五,判断答案是否正确吧 如果答案按钮被填满了,那么就判断用户点击输入的答案是否与标准答案一致,如果一致,则设置答案按钮的文字颜色为蓝色,同时在0.5秒之后跳转下一题 如果答案不一致(答案错误),设置答案按钮的文字颜色为红色, 是不是做这么一个判断,好,那么接下来,我们把这个功能来实现一下,看一下,如果已经满了,上面是不是已经有这个if语句了, if(isFull){ //禁止待选按钮被点击 self.optionsView.userInteractionEnabled = NO; } 其实我们可以直接把这个直接怎样,是不是直接在这个if语句里面判断啊,那么,要想判断答案是否正确,我们是不是需要把那个,当前用户点的这个,每一个答案这个文字是不是拼起来啊,因为这个文字是不是在每一个按钮的title里面, 注意,我们在这个questions.plist里面,每一个模型的这个answer,这是一个完整的字符串吧,这是一个完整的字符串, 你要拿用户输入的每一个按钮上的标题,和这个完整的字符串进行比较,是否一致, 所以说,首先要做的就是,把用户输入的这个、把这个答案按钮上的每一个文字给它拼接成一个字符串吧,然后把这个字符串再和它去比较, 你要进行字符串拼接,首先想到什么,String吧,NSMutableString,要进行字符串拼接,首先想到的是NSMutableString吧, 用NSMutableString,把用户点的答案按钮中的每一个按钮给它拼起来,然后再用这个完整的字符串,和这里这个answer进行比较,isEqual,进行比较,明白,好, 所以说,接下来,我们要做的第一步,就是把用户输入的这个答案文字,用一个完整的NSMutableString拼起来,然后再做比较,第一步拼接字符串, 找到我们这里,在什么地方拼接呢,我们就可以在上面拼接,在这里来拼接,来看 //4.判断答案按钮是否已经填满了 //一开始假设答案按钮是填满的 BOOL isFull = YES; //声明一个用来保存用户输入的答案的字符串,userInput,用户输入的, NSMutableString userInput = [NSMutableString string]; //这样就是一个空的它,然后,接下来,是不是有个for循环啊,在这个for循环中,如果要是这个答案为空,是不是直接就,如果要是有任何一个标题为空,如果要是有任何一个标题为空,表示答案按钮,是不是说并不是一个完整答案啊,如果没填满,下面这个isFull就是NO,如果NO的话,就是不执行里面的代码了, BOOL isFull = YES; NSMutableString userInput = [NSMutableString string]; for(UIButton *btnAnswer in self.answerView.subviews){ if(btnAnswer.currentTitle == nil){ isFull = NO; break; } } if(isFull){ self.optionsView.userInteractionEnabled = NO; } 所以说,如果要是不是空,如果不是空,这个时候我们可以后面给它加个else,else的话,才需要把这个答案给它拼起来, BOOL isFull = YES; NSMutableString userInput = [NSMutableString string]; for(UIButton *btnAnswer in self.answerView.subviews){ if(btnAnswer.currentTitle == nil){ isFull = NO; break; }else { //如果当前答案按钮上面有文字,那么就把这个文字拼接起来, [userInput appendString:btnAnswer.currentTitle]; } } if(isFull){ self.optionsView.userInteractionEnabled = NO; } MutableString怎么来进行拼接字符串,appendString吧,就是说,如果当前这个答案按钮上面有文字,是不是就把这个文字拼起来, 好,那么拼完以后,当这个for循环执行完毕,如果要是每一个按钮都填满了,是不是不可能执行这句话啊,不可能执行if语句里面这句话,就都是执行else, 也就是说,如果答案按钮里面,每一个按钮都填满了,不可能执行isFull = NO;这句话,都是执行else,拼接文字这句话, 那么接下来,当isFull的时候,我们在这个userInput里面,是不是拿到用户输入的那个答案字符串了吧, 好,然后接下来,看一下,这个是用户输入的答案,然后,接下来,在这里要获取当前题目的正确答案, if(isFull){ self.optionsView.userInteractionEnabled = NO; //获取当前题目的正确答案 //获取当前题目的正确答案啊,注意,这是在哪里写代码,是不是我们在一个按钮的单击事件里面吧,在这个按钮的单击事件里面,怎么获取当前这个题目的正确答案,这个题目是在哪里保存的,是不是这个self.questions,是不是这个questions数组里面啊,在这个在这个数组里面,这是不是当前这个索引, //只要根据索引,去数组里面把这个模型取出来,这是不是就是当前题目的模型啊,然后题目那个模型里面,有一个叫做answer的这个属性,这就是正确答案吧,明白我的意思吧,所以说,我们在这个option按钮,btnOption里面单击,获取正确答案,怎么获取呢, TestQuestion *model = self.questions[self.index]; //self.questions这个数组里面,这样就拿到了当前这个模型,self.questions[self.index]; //拿到这个题目的模型,然后,就进行判断,怎么判断呢, //4.如果答案按钮被填满了,那么就判断用户点击输入的答案是否与标准答案一致, if([model.answer isEqualToString:userInput]){ //如果当前的模型的answer,标准答案,isEqualToString:userInput,如果它俩相等,表示什么,userInput什么玩意儿,是不是刚才那个NSMutableString,NSMutableString是什么东西,是不是循环一回,每次你就循环每一个答案按钮,把每一个答案按钮,只要不是空,是不是把它拼起来啊,是每个答案按钮标题拼接起来以后的一个结果吧,拿到这个值,然后用这个值,和标准答案去比较,如果一样,证明答案正确,否则答案错误,如果答案正确,那么接下来,这里面,第一步,设置所有的答案按钮的文字颜色,为什么,蓝色吧, if([model.answer isEqualToString:userInput]){ //如果一致,则设置答案按钮的文字颜色为蓝色,同时在0.5秒之后跳转下一题 //1.设置所有的答案按钮的文字颜色为蓝色, //那么这里是不是设置每一个答案按钮的文字颜色,是不是要循环每一个答案按钮,既然你要循环答案按钮,是不是这儿就需要循环两次,设置一次蓝色,设置一次红色啊,所以说,这个地方你就可以考虑把那个循环,把这个设置答案里的文字颜色,是不是可以给它单独提取一个方法吧,省的我们这儿写两次循环了吧,所以说,注意看,提取一个方法,setAnswerButtonsTitleColor, } else { //如果答案不一致(答案错误),设置答案按钮的文字颜色为红色 //设置所有的答案按钮的文字颜色为红色, } } } //统一设置答案按钮的文字颜色 - (void)setAnswerButtonsTitleColor:(UIColor *)color{ //然后,在里面怎么办,是不是要遍历每一个答案按钮,设置文字颜色啊, //遍历每一个答案按钮,设置文字颜色, for(UIButton *btnAnswer in self.answerView.subviews){ //遍历每个答案按钮,然后怎么办,设置每一个答案按钮的setTitleColor等于什么,等于color, [btnAnswer setTitleColor:color forState:UIControlStateNormal]; } //把颜色传进来,是不是设置每个答案按钮的文字颜色等于这个color,然后当你在这个地方要设置蓝色的时候咋办,[self setAnswerButtonsTitleColor:[UIColor blueColor]]; if([model.answer isEqualToString:userInput]){ //如果一致,则设置答案按钮的文字颜色为蓝色,同时在0.5秒之后跳转下一题 //1.设置所有的答案按钮的文字颜色为蓝色, [self setAnswerButtonsTitleColor:[UIColor blueColor]]; } else { //如果答案不一致(答案错误),设置答案按钮的文字颜色为红色 //设置所有的答案按钮的文字颜色为红色, [self setAnswerButtonsTitleColor:[UIColor redColor]]; } 运行一下,试试看,这是答案错误吧, 这是答案正确吧, 是不是现在是对了,就是说,当你就是答案输错以后,变成红了,当你单击任何一个答案按钮的时候,是不是再把所有的答案按钮的文字再设置成黑色啊, 所以说,在你点击答案按钮里面,还应该再做一步,就是设置所有的答案按钮的文字颜色是不是黑色, 所以说,在我们的答案按钮的单击事件里面,找到搜索answer,找到btnAnswerClick方法,答案按钮的单击事件里面,怎么办,是不是要设置每一个答案按钮的文字颜色啊, - (void)btnAnswerClick:(UIButton *)sender{ //0.启用option view与用户交互, self.optionsView.userInteractionEnabled = YES; //1.现在,我要做的是干什么,我要做的是,当你一开始填错以后,是不是答案按钮的文字都变成红色了,然后当你点击任何一个答案按钮的时候,一点它,要把所有的答案按钮的文字颜色设置成黑色,所以说,我们找到这个答案按钮的单击事件吧,btnAnswerClick,这个事件,然后在里面,其中有一步就是,设置答案按钮的文字颜色为黑色, //1.设置所有的答案按钮的文字颜色为黑色, //怎么设置,调用刚才已经写好的setAnswerButtonsTitleColor方法吧, [self setAnswerButtonsTitleColor:[UIColor blackColor]]; } 运行一下,是不是好了, 三、当答案正确以后,是不是0.5秒钟之后,自动跳到下一题啊, 1.第一,是怎么实现0.5秒之后,执行一个方法, 对,延迟吧,哪个是延迟,就是performSelector,是不是延迟啊, 那么,接下来,假设没有这个延迟,当输入正确以后,马上跳到下一题,怎么实现啊, 直接调用nextQuestion,调一下,是不是就直接自动进入下一题了, 是不是相当于点了“下一题”这个按钮啊, 我们在这个“下一题”按钮中,在这个btnNextClick,在这个下一题这个按钮的点击事件中,是不是调了这个nextQuestion这个方法啊 //点击下一题 - (IBAction)btnNextClick{ //移动到下一题 [self nextQuestion]; } 也就意味着,当我们延迟0.5秒钟以后,只要调一下nextQuestion方法,就会自动进入下一题啊, 好,接下来,找到我们这个option按钮的单击事件,在这个里面,我们找到,在这个待选按钮单击事件里面, //待选按钮的单击事件 - (void)optionButtonClick:(UIButton *)sender{ //1.隐藏当前被点击的按钮 sender.hidden = YES; //2.把当前被点击的按钮的文字显示到第一个为空的答案按钮上 NSString *text = sender.currentTitle; //2.1 把文字显示到答案按钮上 for(UIButton *answerBtn in self.answerView.subviews){ //判断每个答案按钮上的文字是否为nil if(answerBtn.currentTitle == nil){ //把当前点击的待选按钮的文字,设置给对应的答案按钮 [answerBtn setTitle:text forState:UIControlStateNormal]; //把当前点击的待选按钮的tag值也设置给对应的答案按钮 answerBtn.tag = sender.tag; break; } } //3.判断答案按钮是否已经满了 //一开始,假设答案按钮是满的 BOOL is Full = YES; //声明一个用来储存用户输入的答案的字符串 NSMutableString *userInput = [NSMutableString string]; for(UIButton *btnAnswer in self.answerView.subviews){ if(btnAnswer.currentTitle == nil){ isFull = NO; break; } else { //如果当前答案按钮上面有文字,那么就把这个文字拼接起来 [userInput appendString:btnAnswer.currentTitle]; } } //如果已经填满,则禁止option view控件与用户交互 if(isFull){ //禁止待选按钮被点击 self.optionsView.userInteractionEnabled = NO; //获取当前题目的正确答案 TestQuestion *model = self.question[self.index]; //4.如果答案按钮被填满了,那么就判断用户点击输入的答案是否与标准答案一致 if([model.answer isEqualToString:userInput]){ //如果一致,则设置答案按钮的文字颜色为蓝色,同时在0.5秒钟之后跳转到下一题 //1.设置所有的答案按钮的文字颜色为蓝色 [self setAnswerButtonsTitleColor:[UIColor blueColor]]; //好,在这个里面,我们找到,在待选按钮单击事件里面,如果当题目答案正确的话,接下来,延迟0.5秒, //延迟0.5秒后,跳转到下一题 //怎么延迟呢,让当前这个控制器,是不是执行一个方法,peformSelector,执行哪个方法呢,是不是执行这个nextQuestion,然后呢,参数有吗,没有,withObject:nil, afterDelay:(NSTimeInterval),多长时间呢,0.5秒, [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5]; //是不是0.5秒钟之后,调一下这个nextQuestion方法吧, } else { //如果答案不一致(答案错误),设置答案按钮的文字颜色为红色 //设置所有的答案按钮的文字颜色为红色 [self setAnswerButtonsTitleColor:[UIColor redColor]]; } } } 运行一下试试,是不是过来了, 四、当你输入正确答案之后,跳转到了下一题,但是option按钮是不是还是不可用啊,这是为什么, 1.因为你执行完nextQuestion方法的时候,它只是把所有的option按钮给你删掉了,又重新创建了一遍,但是这个蓝色的view,是不是还是之前那个蓝色的view啊,之前答案按钮填满了之后,我们是不是让这个蓝色的view变得不可用了,所以这时候,你还要在nextQuestion方法里面,找到这个创建option按钮的方法,makeOptionsButton,在这个方法里面,是不是要让这个蓝色的view变得可用啊 2.每次创建这个option按钮的时候,先让这个蓝色的view变得可用: //创建待选按钮 - (void)makeOptionsButton:(TestQuestion *)model{ //0.设置option view self.optionsView.userInteractionEnabled = YES; } 3.运行一下试试,是不是可以了,但是还有一个问题,如果7道题都答对了,最后一套题答完之后,程序会崩溃,为什么崩, 因为我们如果点“下一题”按钮,到最后一题的时候,这个“下一题”按钮是不是不能点了吧,但是你通过程序自动跳转到“下一题”,是不是最后一道题答对了以后,还是能通过程序跳转到下一题啊,还能执行这个nextQuestion方法啊,所以,你在这个nextQuestion方法里面,不仅要让“下一题”按钮禁用,还要判断一下索引是否越界,越界的话,要做一些操作啊, 所以说,我们在nextQuestion方法当中,找到nextQuestion方法, //下一题 - (void)nextQuestion{ //1.让索引++ self.index++; //2.根据索引获取当前的模型数据 TestQuestion *model = self.questions[self.index]; //3.根据模型设置数据 [self settingData:model]; //4.动态创建答案按钮 [self makeAnswerButtons:model]; //5.动态创建待选项按钮 [self makeOptionsButton:model]; } 在这个方法当中,我们这里得做一下判断,当你这个index++以后,得判断一下, //判断当前索引是否越界,如果索引越界,则提示用户 if(self.index //怎么样,索引就越界了,如果self.index == self.questions.count - 1,这是到了最后一个吧,如果到了最后一个,还没有越界,但是,如果等于了self.questions.count,就越界了吧, if(self.index == self.questions.count ) { //既然你已经越界了,后面代码还要执行吗,不执行了,所以说,直接return,就行了吧, NSLog(@“答题完毕!”); return; } 好,下一个将要实现的功能,是弹出一个对话框,提示用户答题完毕, 好了,这就是我们这个判断答案是否正确,