通过上一篇已经熟悉了对xib的使用,字典转模型,九宫格的使用,现在继续通过案例-猜图 巩固一下这些知识点。
效果图如下:
分析:
1.答案输入框个数是根据答案的长度实现,答案选择格子不同题目的选择答案不一样,因此要动态创建ui,其它的可以使用storyboard创建。
2.每猜对就加分,点击提示按钮就自动显示第一个答案。
3.点击大图按钮就显示大图,点击图片时如果目前是大图就变成大图,目前是小图就变大图显示(利用遮掩层实现)。
4.点击待选择答案就把改答案实现在输入框中,并删除该待选文字。
5.点击下一题就进入下一题,全部完成后就提示 是否过关。
1.storyboard创建ui界面,并连线
2.新建问题模型
ZXHQuestion.h
//
// ZXHQuestion.h
#import <Foundation/Foundation.h>
/**
* 题目数据模型
*/
@interface ZXHQuestion : NSObject
/**
* 答案
*/
@property(nonatomic,copy) NSString *answer;
/**
* 题目
*/
@property(nonatomic,copy) NSString *title;
/**
* 图标
*/
@property(nonatomic,copy) NSString *icon;
/**
* 答案选项
*/
@property(nonatomic,strong) NSArray *options;
/**
* 字典转化模型
*
* @param dict 字典
*
* @return 模型对象
*/
-(instancetype)initWithDict:(NSDictionary *)dict;
/**
* 字典转换模型(类方法)
*
* @param dict 字典
*
* @return 模型对象
*/
+(instancetype)questionWithDict:(NSDictionary *)dict;
@end
ZXHQuestion.m
//
// ZXHQuestion.m
#import "ZXHQuestion.h"
@implementation ZXHQuestion
/**
* 字典转化模型
*
* @param dict 字典
*
* @return 模型对象
*/
-(instancetype)initWithDict:(NSDictionary *)dict{
if (self = [super init]) {
self.answer = dict[@"answer"];
self.title = dict[@"title"];
self.icon = dict[@"icon"];
self.options = dict[@"options"];
}
return self;
}
/**
* 字典转化模型(类型)
*
* @param dict 字典
*
* @return 模型对象
*/
+(instancetype)questionWithDict:(NSDictionary *)dict{
return [[self alloc]initWithDict:dict];
}
@end
3.业务逻辑处理
//
// ViewController.m
#import "ViewController.h"
#import "ZXHQuestion.h"
@interface ViewController ()<UIAlertViewDelegate>
/**
* 提示方法
*/
- (IBAction)tip;
/**
* 帮助方法
*/
- (IBAction)help;
/**
* 显示大图方法
*/
- (IBAction)btnImg;
/**
* 下一题
*/
- (IBAction)nextQuestion;
/**
* 点击图片
*/
- (IBAction)imgClick;
/*序号*/
@property (weak, nonatomic) IBOutlet UILabel *noLabel;
/*标题*/
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
/*分数*/
@property (weak, nonatomic) IBOutlet UIButton *scoreBtn;
/*下一题按钮*/
@property (weak, nonatomic) IBOutlet UIButton *nextBtn;
/*图片按钮*/
@property (weak, nonatomic) IBOutlet UIButton *imgBtn;
/*遮掩层*/
@property(weak,nonatomic) IBOutlet UIButton *cover;
/*存放正确答案view*/
@property(weak,nonatomic) IBOutlet UIView *answerView;
/*存放可选答案view*/
@property(weak,nonatomic) IBOutlet UIView *optionView;
/**
* 所有题目
*/
@property(nonatomic,strong) NSArray *questions;
/**
* 数组下标
*/
@property(nonatomic,assign) int index;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.index = -1;
[self nextQuestion];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/**
* 从写get方法
*
* @return 所有题目数组
*/
-(NSArray *)questions{
//懒加载
if (_questions == nil) {
// 1.加载plist
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"questions" ofType:@"plist"]];
//字典转换为模型
NSMutableArray *questionArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
ZXHQuestion *question = [ZXHQuestion questionWithDict:dict];
[questionArray addObject:question];
}
_questions = questionArray;
}
return _questions;
}
/**
* 提示
*/
- (IBAction)tip {
//清楚答案按钮所有文字,调用answerClick
for (UIButton *answerBtn in self.answerView.subviews) {
[self answerClick:answerBtn];
}
//获取正确答案(第一个字)
ZXHQuestion *question = self.questions[self.index];
NSString *answerfirst = [question.answer substringToIndex:1];
//给答案第一个按钮赋正确值
for (UIButton *optionBtn in self.optionView.subviews) {
if ([optionBtn.currentTitle isEqualToString:answerfirst]) {
[self optionClick:optionBtn];
break;
}
}
//减分
[self addScore:-800];
}
- (IBAction)help {
}
/**
* 大图
*/
-(IBAction)btnImg{
//添加阴影
UIButton *cover = [[UIButton alloc]init];
cover.frame = self.view.bounds;
cover.backgroundColor = [UIColor blackColor];
cover.alpha = 0.0;
[cover addTarget:self action:@selector(smallImg) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:cover];
self.cover = cover;
//更换阴影和头像的位置(将图片现在在最上面)
[self.view bringSubviewToFront:self.imgBtn];
//3.执行动画
[UIView animateWithDuration:0.25 animations:^{
//阴影慢慢显示出来
cover.alpha = 0.7;
//头像慢慢变大,慢慢移动到屏幕的中间
CGFloat iconW = self.view.frame.size.width;
CGFloat iconH = iconW;
CGFloat iconY = (self.view.frame.size.height - iconH) * 0.5;
self.imgBtn.frame = CGRectMake(0, iconY, iconW, iconH);
}];
}
/**
* 小图
*/
-(IBAction)smallImg{
//执行动画
[UIView animateWithDuration:0.25 animations:^{
// 1.头像慢慢变为原来的位置和尺寸
self.imgBtn.frame = CGRectMake( 85, 107, 150, 150);
// 2.阴影慢慢消失
self.cover.alpha = 0.0;
}completion:^(BOOL finished){
// 动画执行完毕后会自动调用这个block内部的代码
// 动画执行完毕后,移除遮盖(从内存中移除)
[self.cover removeFromSuperview];
self.cover = nil;
}];
}
/**
* 下一题
*/
- (IBAction)nextQuestion {
//最后一题
if (self.index == self.questions.count-1) {
//提示框
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"恭喜!" message:@"您已经闯关成功!" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
[alertView show];
alertView.tag = 10;
// UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"恭喜通关" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:@"其他", nil];
//
// [sheet showInView:self.view];
return;
}
//下标索引
self.index ++;
//取出模型
ZXHQuestion *question = self.questions[self.index];
//设置控件数据
[self settingData:question];
//正确答案
[self addAnswerBtn:question];
// 添加待选项
[self addOptionBtn:question];
}
/**
* 提示框监听事件
*
* @param alertView 提示框view 当有多个提示框时候可以用此区别
* @param buttonIndex 点击按钮下标
*/
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSInteger tag = alertView.tag;
NSLog(@"点击了tag为%ld,下标为%ld的按钮",tag,buttonIndex);
}
/**
* 设置控件数据
*
* @param question 题目模型
*/
-(void)settingData:(ZXHQuestion *)question{
//设置序号
self.noLabel.text = [NSString stringWithFormat:@"%d/%ld",self.index+1,self.questions.count];
//设置标题
self.titleLabel.text = question.title;
//设置图片
[self.imgBtn setImage:[UIImage imageNamed:question.icon] forState:UIControlStateNormal];
//设置下一题按钮
self.nextBtn.enabled= self.index != (self.questions.count-1);
}
/**
* 点击图片
*/
-(IBAction)imgClick{
if (self.cover == nil) {//没有阴影调显示大图方法
[self btnImg];
}else{
[self smallImg];//调用显示小图方法
}
}
/**
* 添加正确答案
*
* @param question 模型
*/
-(void)addAnswerBtn:(ZXHQuestion *)question{
//删除之前所有的按钮
// for (UIView *subview in self.answerView.subviews) {
// [subview removeFromSuperview];
// }
//让数组所有对象执行removeFromSuperview
[self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
//添加新按钮
int length = (int)question.answer.length;
for (int i = 0 ; i<length; i++) {
//创建按钮
UIButton *answerBtn = [[UIButton alloc]init];
[answerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
// 设置背景
[answerBtn setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal];
[answerBtn setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState:UIControlStateHighlighted];
// 设置frame
// 控制器view的宽度
CGFloat viewW = self.view.frame.size.width;
// 按钮之间的间距
CGFloat margin = 10;
// 按钮的尺寸
CGFloat btnW = 35;
CGFloat btnH = 35;
// 最左边的间距 = 0.5 * (控制器view的宽度 - 按钮个数 * 按钮宽度 - (按钮个数 - 1) * 按钮之间的间距)
CGFloat leftMargin = 0.5 *(viewW - length * btnW - (length - 1) * margin);
// 按钮的x = 最左边的间距 + i * (按钮宽度 + 按钮之间的间距)
CGFloat btnX = leftMargin + i * (btnW + margin);
CGFloat btnY = 0;
answerBtn.frame = CGRectMake(btnX, btnY, btnW, btnH);
// 5.2.4.添加
[self.answerView addSubview:answerBtn];
//添加点击监听
[answerBtn addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside];
}
}
/**
* 添加待选按钮
*
* @param question 模型
*/
-(void)addOptionBtn:(ZXHQuestion *) question{
//删除之前所有的按钮
// for (UIView *subView in self.optionView.subviews) {
// [subView removeFromSuperview];
// }
//让待选按钮能够被点击
self.optionView.userInteractionEnabled = YES;
[self.optionView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
//添加新按钮
int length = (int)question.options.count;
for (int i = 0; i<length; i++) {
//创建按钮
UIButton *optionBtn = [[UIButton alloc]init];
[optionBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
// 设置背景
[optionBtn setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
[optionBtn setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted];
// 设置frame
// 控制器view的宽度
CGFloat viewW = self.view.frame.size.width;
// 按钮之间的间距
CGFloat margin = 10;
// 按钮的尺寸
CGFloat btnW = 35;
CGFloat btnH = 35;
//总列数
int totalColumns = 7;
// 最左边的间距 = 0.5 * (控制器view的宽度 - 按钮个数 * 按钮宽度 - (按钮个数 - 1) * 按钮之间的间距)
CGFloat leftMargin = 0.5 *(viewW - totalColumns * btnW - (totalColumns - 1) * margin);
//列数
int col = i % totalColumns;
//按钮的x = 最左边的间距 + 列号 * (按钮宽度 + 按钮之间的间距)
CGFloat btnX = leftMargin + col * (btnW + margin);
//行数
int row = i / totalColumns;
// 按钮的y = 行号 * (按钮高度 + 按钮之间的间距)
CGFloat btnY = row * (btnH + margin);
optionBtn.frame = CGRectMake(btnX, btnY, btnW, btnH);
// 设置文字
[optionBtn setTitle:question.options[i] forState:UIControlStateNormal];
[optionBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
//添加按钮
[self.optionView addSubview:optionBtn];
//监听点击
[optionBtn addTarget:self action:@selector(optionClick:) forControlEvents:UIControlEventTouchUpInside];
}
}
/**
* 监听答案按钮的点击
*
* @param answerBtn 正确答案btn
*/
-(void)answerClick:(UIButton *)answerBtn{
//让待选按钮能够被点击
self.optionView.userInteractionEnabled = YES;
// 答案按钮的文字
NSString *answerTitle = [answerBtn titleForState:UIControlStateNormal];
// 1.让答案按钮文字对应的待选按钮显示出来(hidden = NO)
for (UIButton *optionBtn in self.optionView.subviews) {
NSString *optionTitle = [optionBtn titleForState:UIControlStateNormal];
if ([optionTitle isEqualToString:answerTitle] && optionBtn.hidden == YES) {
optionBtn.hidden = NO;
break;
}
}
// 2.让被点击答案按钮的文字消失(去除文字)
[answerBtn setTitle:nil forState:UIControlStateNormal];
// 3.让所有的答案按钮变为黑色
for (UIButton *answerBtn in self.answerView.subviews) {
[answerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
}
}
/**
* 监听待选按钮的点击
*
* @param optionBtn 待选按钮
*/
-(void)optionClick:(UIButton *)optionBtn{
//显示文字到正确答案
for (UIButton * answerBtn in self.answerView.subviews) {
//判断按钮是否有文字
//NSString *answerTitle = [answerBtn titleForState:UIControlStateNormal];
NSString *answerTitle = answerBtn.currentTitle;
if (answerTitle.length == 0) { // 没有文字
// 设置答案按钮的 文字 为 被点击待选按钮的文字
//NSString *optionTitle = [optionBtn titleForState:UIControlStateNormal];
NSString *optionTitle = optionBtn.currentTitle;
[answerBtn setTitle:optionTitle forState:UIControlStateNormal];
//让被点击的选择按钮消失
optionBtn.hidden = YES;
break;// 停止遍历
}
}
// 3.检测答案是否填满
BOOL full = YES;
//存储答案
NSMutableString *tempAnswerTitle = [NSMutableString string];
for (UIButton *answerBtn in self.answerView.subviews) {
//NSString *answerTitle = [answerBtn titleForState:UIControlStateNormal];
NSString *answerTitle = answerBtn.currentTitle;
if (answerTitle.length== 0) {
full = NO;
}
//拼接答案
if (answerTitle) {
[tempAnswerTitle appendString:answerTitle];
}
}
// 4.答案满了
if (full) {
//让待选按钮不能够被点击
self.optionView.userInteractionEnabled = NO;
// for(UIButton *button in self.optionView.subviews){
// button.enabled = NO;
// }
ZXHQuestion *question = self.questions[self.index];
if ([tempAnswerTitle isEqualToString:question.answer]) {//答对
//显示蓝色
for (UIButton *answerBtn in self.answerView.subviews) {
[answerBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
}
//加分
// int score = [self.scoreBtn titleForState:UIControlStateNormal].intValue;
[self addScore:1000];
//0.5秒后跳下一题
[self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5];
}else{//答错
//显示红色
for (UIButton *answerBtn in self.answerView.subviews) {
[answerBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
}
}
}
}
/**
* 减分,加分
*
* @param score 分数
*/
-(void)addScore:(int)score{
int totalScore = self.scoreBtn.currentTitle.intValue;
totalScore += score;
[self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",totalScore] forState:UIControlStateNormal];
}
@end
-------------------文字至此!