AJ分享,必须精品

先看效果图






思路

需求分析

1,搭建界面
1》上半部分,固定的,用Storyboard直接连线(OK)
2》下半部分,根据题目的变化,不断变化和调整,用代码方式实现比较合适(OK)
*备选按钮区域(OK)
*答案按钮区域(OK)

2,编写代码
1》大图,小图的切换(OK)
2》下一题(OK)
3》备选按钮的点击,让文字进入答案区(Ok)
4》判断对错胜负(OK)
*胜利:进入下一题(OK)
*失败:提示用户重新选择(OK)
5》答案按钮的点击(OK)
把答案区的文字回复到备选区域(Ok)

代码



//

//  NYViewController.m
// 01-超级猜图游戏
//
// Created by apple on 15-3-21.
// Copyright (c) 2015年 znycat. All rights reserved.
// #import "NYViewController.h"
#import "NYQuestion.h" @interface NYViewController () @property (weak, nonatomic) IBOutlet UIButton *iconButton; @property (nonatomic, strong) UIButton *cover; @property (nonatomic, strong) NSArray *questions;
@property (weak, nonatomic) IBOutlet UILabel *noLabel; @property (weak, nonatomic) IBOutlet UILabel *titleLabel; @property (weak, nonatomic) IBOutlet UIButton *nextQuestionButton;
@property (weak, nonatomic) IBOutlet UIView *answerView; @property (weak, nonatomic) IBOutlet UIView *optionsView; @property (weak, nonatomic) IBOutlet UIButton *scoreButton; /** 题目索引*/
@property (nonatomic, assign) int index; @end @implementation NYViewController
#define kButtonWidth 35
#define kButtonHeight 35
#define kButtonMargin 10
#define kTotolCol 7 -(NSArray *)questions
{
if (_questions == nil) {
_questions = [NYQuestion questions];
}
return _questions;
} -(UIButton *)cover{
if (_cover == nil) {
//1,添加蒙版(遮罩)
_cover = [[UIButton alloc] initWithFrame:self.view.bounds];
_cover.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
[self.view addSubview:_cover];
_cover.alpha = 0.0; [_cover addTarget:self action:@selector(bigImage) forControlEvents:UIControlEventTouchUpInside];
}
return _cover;
} - (void)viewDidLoad
{
[super viewDidLoad];
self.index = -1;
[self nextQuestion]; } //设置状态栏为亮色,可以显示(最上面显示时间信号那一行)
- (UIStatusBarStyle)preferredStatusBarStyle
{
// UIStatusBarStyleDefault = 0,黑色黑色状态栏
// StatusBarStyleLightContent NS_ENUM_AVAILABLE_IOS(7_0) = 1,亮色状态栏
return UIStatusBarStyleLightContent;
} #pragma mark - 大图小图切换
/**
*大图小图显示切换
*/
- (IBAction)bigImage
{
//如果没有放大就放大,放大了就缩小
//通过判断iconButton的大小
if (self.cover.alpha == 0) {
//2,把图像按钮放到最前边
[self.view bringSubviewToFront:self.iconButton];
//3,动画放大图像按钮 CGFloat w = self.view.bounds.size.width;
CGFloat h = w;
CGFloat y = (self.view.bounds.size.height-h)*0.5;
[UIView animateWithDuration:1.0 animations: ^{
self.iconButton.frame = CGRectMake(0, y, w, h);
self.cover.alpha = 1.0; }];
}else{//缩小图片 //将图片恢复初始位置
[UIView animateWithDuration:1.0 animations:^{
self.iconButton.frame = CGRectMake(85, 85, 150, 150);
self.cover.alpha = 0.0;//让遮罩逐渐消失
}];
}
} #pragma mark - 下一题
/**
*下一个题目
*
*主要的方法,尽量保留简短的代码,主要体现思路和流程即可。
*/
-(IBAction)nextQuestion{ //1,当前答题的索引,索引递增
self.index ++;
//如果index到达最后一个题,那么提示用户,播放动画。。。
if (self.index == self.questions.count) {
NSLog(@"通关啦!!!");
return;
} //2,从数组中按照索引取出题目数据模型
NYQuestion *question = self.questions[self.index];
//3,设置基本信息
[self setupBasicInfo:question];
//4,设置答案按钮
[self creatAnswerButton:question];
//5,设置备选按钮
[self creatOptionsButton:question];
} /** 设置基本信息*/
-(void)setupBasicInfo:(NYQuestion *)question
{
self.noLabel.text = [NSString stringWithFormat:@"%d/%d",self.index+1,self.questions.count ];
self.titleLabel.text = question.title;
[self.iconButton setImage:[UIImage imageNamed:question.icon] forState:UIControlStateNormal]; //如果达到最后一题,禁用一下按钮
self.nextQuestionButton.enabled = (self.index < self.questions.count-1);
}
/** 创建答案区按钮*/
-(void)creatAnswerButton:(NYQuestion *)question
{
//删除answerView已经存在的控件
for (UIView *btn in self.answerView.subviews){
[btn removeFromSuperview];
} CGFloat answerW = self.answerView.bounds.size.width;
int length = question.answer.length;//答案的字符数量
CGFloat answerX = (answerW - length*kButtonWidth - (length-1)*kButtonMargin)*0.5;//答案按钮开始的第一个字的最左边坐标 //创建所有答案的按钮
for (int i = 0; i<length; i++) {
CGFloat x = answerX + i*(kButtonWidth + kButtonMargin);
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, kButtonWidth, kButtonHeight)];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"bn_answer_highlighted" ] forState:UIControlStateHighlighted];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.answerView addSubview:btn]; [btn addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside];
}
}
/** 创建备选区按钮*/
-(void)creatOptionsButton:(NYQuestion *)question
{
//问题:每次调用下一题方法时,都会重新创建21个按钮
//解决:如果按钮已经存在,并且是21个,只需要更改按钮标题即可 if (self.optionsView.subviews.count != question.options.count) {
//定义行和列
CGFloat optionW = self.optionsView.bounds.size.width;
CGFloat optionX = (optionW - kButtonWidth*kTotolCol - kButtonMargin *(kTotolCol-1))*0.5;
for(int i = 0 ; i<question.options.count;i++)
{
int row = i/kTotolCol;//行
int col = i%kTotolCol;//列 CGFloat x = optionX + col * (kButtonMargin+kButtonWidth);
CGFloat y = row * (kButtonHeight+kButtonMargin); UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, kButtonWidth, kButtonHeight)]; /*喵了个咪的,这里出了这么一个错误
每一个按钮可以有8张图片,4个状态每个状态有两个,image和backgroundImage,如果你设置了image图片那么你的设置的title将会被你的image挤开到一边,如果你的image大的话你就真的看不到他了*/
// [btn setImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
// [btn setImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted]; [btn setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted];
//添加备选区域按钮标题 [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];//设置标题颜色 [self.optionsView addSubview:btn];//用爹来添加,删除时候是用爹找到所有儿子然后让儿子自己删自己 //添加被选取按钮点击事件
[btn addTarget:self action:@selector(optionClick:) forControlEvents:UIControlEventTouchUpInside]; }
} //如果按钮已经存在,在点击下一题的时候,只需要设置标题即可
int i = 0; for (UIButton *btn in self.optionsView.subviews){
//设置标题内容
[btn setTitle:question.options[i++] forState:UIControlStateNormal]; //取消按钮的隐藏
btn.hidden = NO;
} } #pragma mark - 备选按钮点击方法
/**添加被选取按钮点击事件*/
-(void)optionClick:(UIButton *)button
{
//1,在答案区找到第一个标题为空的按钮
UIButton *ansBtn = [self firstAnswerButton];
if (ansBtn == nil)return;
//2,将button的标题赋值给答案去的按钮
[ansBtn setTitle:button.currentTitle forState:UIControlStateNormal];
//3,隐藏按钮
button.hidden = YES;
//4,判断结果
[self judge];
} /**判断结果*/
-(void)judge{ //如果答题区按钮都有答案,才需要判断结果
//遍历所有答题区的按钮
BOOL isFull = YES;
NSMutableString * strM = [NSMutableString string]; for(UIButton * btn in self.answerView.subviews)
{
if (btn.currentTitle.length == 0) {
//只要有一个按钮没有字 //
isFull = NO;
break;//跳出循环
}else{//有字,拼接临时字符串
[strM appendString:btn.currentTitle];
}
} if (isFull) {
NSLog(@"都有字");
NYQuestion *question = self.questions[self.index];//得到问题
//判断是否和答案一致,
if([question.answer isEqualToString:strM]){//判断问题和字符串是否相等
//如果相等
NSLog(@"答对了");
//如果一致,设置成蓝色进入下一题
[self setAnswerButtonColor:[UIColor blueColor]];
//等待0.5秒,进入下一题
[self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5];
}else{
NSLog(@"答错了");
//如果不一致,修改按钮文字颜色,提示用户
[self setAnswerButtonColor:[UIColor redColor]];
}
}else {
NSLog(@"继续");
}
}
/**修改答题区按钮的颜色*/
-(void)setAnswerButtonColor:(UIColor *)color
{
for (UIButton *btn in self.answerView.subviews) {
[btn setTitleColor:color forState:UIControlStateNormal];
}
} /**在答案区找到第一个标题为空的按钮
如果答案区按钮都满了就返回nil
*/
-(UIButton *) firstAnswerButton
{
// 取出按钮标题,遍历答题区按钮
for (UIButton *btn in self.answerView.subviews) {
if (btn.currentTitle.length == 0) {
return btn;
}
}
return nil;
} #pragma mark - 答题区按钮点击方法
-(void)answerClick:(UIButton *)button
{
//如果按钮没有字,直接返回
if (button.currentTitle.length == 0) {
return;
}
//如果有字,清除文字,候选区按钮显示
//1,使用button的title去查找候选区中对应的按钮
UIButton *btn = [self optionButtonWithTitle:button.currentTitle isHidden:YES];
//2,显示对应按钮
btn.hidden = NO;
//3,清除答案区button的文字
[button setTitle:@"" forState:UIControlStateNormal];
//4,只要点击了按钮,答题区就少了,然后就设成黑色
[self setAnswerButtonColor:[UIColor blackColor]]; } /**遍历备选的按钮 如果返回与title相同 并且 hidden为YES(隐藏) 的btn*/
-(UIButton *) optionButtonWithTitle:(NSString *)title isHidden:(BOOL) isHidden
{ for (UIButton *btn in self.optionsView.subviews) {
if ([btn.currentTitle isEqualToString:title] && btn.hidden) {
return btn;
}
}
return nil;
} #pragma mark - 提示功能
-(IBAction)tipClick
{
//1,把答题区的所有的按钮清空
for (UIButton *btn in self.answerView.subviews) {
// [btn setTitle:@"" forState:UIControlStateNormal];
[self answerClick:btn];
}
//2,把正确答案的第一个字,设置到答题区中
//找到答案的第一个字
NYQuestion *question = self.questions[self.index];
NSString *first = [question.answer substringToIndex:1];
//取出文字对应的候选按钮
// for (UIButton *btn in self.optionsView.subviews) {
// if ([btn.currentTitle isEqualToString:first] && !btn.hidden) {
// [self optionClick:btn];//找到正确答案后按一下,然后自动就上答案区了
// break;
// }
// }
UIButton * btn = [self optionButtonWithTitle:first isHidden:NO];
[self optionClick:btn]; //提示的时候需要扣分
[self changeScore:-1000]; } #pragma mark - 分数处理
-(void)changeScore:(int) score
{
//取出当前分数
int currentScore = self.scoreButton.currentTitle.intValue;
//使用score调整分数
currentScore += score;
//重新设置分数
[self.scoreButton setTitle:[NSString stringWithFormat:@"%d",currentScore ] forState:UIControlStateNormal];
} @end

字典的代码

//
// NYQuestion.h
// 01-超级猜图游戏
//
// Created by apple on 15-3-21.
// Copyright (c) 2015年 znycat. All rights reserved.
// #import <Foundation/Foundation.h> @interface NYQuestion : NSObject
@property (nonatomic, copy) NSString *answer;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) NSArray *options; -(instancetype)initWithDict:(NSDictionary *)dict;
+(instancetype)questionWithDick:(NSDictionary *)dict; /**
*返回所有题目数组
*/
+(NSArray *)questions; /**打乱备选文字的数组*/
-(void)randomOptions;
@end //
// NYQuestion.m
// 01-超级猜图游戏
//
// Created by apple on 15-3-21.
// Copyright (c) 2015年 znycat. All rights reserved.
// #import "NYQuestion.h" @implementation NYQuestion //相当于构造方法(用NSDictionary 字典构造)
-(instancetype)initWithDict:(NSDictionary *)dict
{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
//让模型打乱数据
[self randomOptions];
}
return self;
} //提供类方法来调用initWithDict:dict方法,方便调用
+(instancetype)questionWithDick:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict]; } /**
*返回所有题目数组
*/
+(NSArray *)questions
{
//array中是文件中的字典数组
NSArray *array = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"questions.plist" ofType:nil]];
//初始化一个可以添加的数组为了存放模型数据
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dict in array) {
[arrayM addObject:[self questionWithDick:dict]];
} return arrayM;
} -(void)randomOptions
{
//对options做乱序
self.options = [self.options sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
int seed = arc4random_uniform(2);
if (seed) {
return [str1 compare:str2];
}else
{
return [str2 compare:str1];
} }];
} @end

上面是全部代码,
学习过程首先自己拖界面上半部分,需求里面写的很清楚了,

注释当中写的相当清楚,每个mark都间隔出来了部分的功能,因为是学习写的代码,所以注释写的很全,应该可以看懂。

完成布局后就开始写模型字典了。这里就用到了mvc设计模式,当然这个游戏中主要用到的时mc view方面并不是那么多,主要是对设计逻辑的学习与体现。

然后就按照需求来设计学习编写啦。

AJ学IOS(06)UI之iOS热门游戏_超级猜图的更多相关文章

  1. iOS开发UI篇—IOS开发中Xcode的一些使用技巧

    iOS开发UI篇—IOS开发中Xcode的一些使用技巧 一.快捷键的使用 经常用到的快捷键如下: 新建 shift + cmd + n     新建项目 cmd + n             新建文 ...

  2. iOS开发UI篇—iOS开发中三种简单的动画设置

    iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...

  3. iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)

    iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...

  4. iOS开发UI篇—ios应用数据存储方式(偏好设置)

    iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...

  5. iOS开发UI篇—ios应用数据存储方式(归档)

    iOS开发UI篇—ios应用数据存储方式(归档)  一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同 ...

  6. iOS开发UI篇—ios应用数据存储方式(归档) :转发

    本文转发至:文顶顶http://www.cnblogs.com/wendingding/p/3775293.html iOS开发UI篇—ios应用数据存储方式(归档)  一.简单说明 在使用plist ...

  7. AJ学IOS(28)UI之Quartz2D简单介绍

    AJ分享,必须精品 iOS开发UI篇—Quartz2D简单介绍 什么是Quartz2D Quartz 2D是⼀个二维绘图引擎,同时支持iOS和Mac系统 Quartz 2D能完成的工作: 绘制图形 : ...

  8. [Android开发学iOS系列] iOS写UI的几种方式

    [Android开发学iOS系列] iOS写UI的几种方式 作为一个现代化的平台, iOS的发展也经历了好几个时代. 本文讲讲iOS写UI的几种主要方式和各自的特点. iOS写UI的方式 在iOS中写 ...

  9. 06 (OC)* iOS中UI类之间的继承关系

    iOS中UI类之间的继承关系 此图可以更好的让你去理解iOS中一些底层的关系.你能够了解以及理解UI类之间的继承关系,你会更加明白苹果有关于底层的东西,更有助于你的项目开发由它们的底层关系,就能更加容 ...

随机推荐

  1. 【ES】Java High Level REST Client 使用示例(增加修改)

    ES提供了多种编程语言的链接方式,有Java API,PHP API,.NET API 官网可以详细了解 https://www.elastic.co/guide/en/elasticsearch/c ...

  2. Journal of Proteome Research | Down-Regulation of a Male-Specific H3K4 Demethylase, KDM5D, Impairs Cardiomyocyte Differentiation (男性特有的H3K4脱甲基酶基因(KDM5D)下调会损伤心肌细胞分化) | (解读人:徐宁)

    文献名:Down-Regulation of a Male-Specific H3K4 Demethylase, KDM5D, Impairs Cardiomyocyte Differentiatio ...

  3. SpringBoot2 线程池的定义和使用

    SpringBoot2 线程池的定义和使用 定义线程池 @Slf4j @EnableAsync @Configuration public class AsyncExecutorConfig impl ...

  4. 【简说Python WEB】pyechart在flask中的应用

    个人笔记总结,可读性不高.只为自己总结用.怕日后忘记. 这里用到了tushare,pandas等python组件. pyechart的案例 c = ( Bar() .add_xaxis([" ...

  5. CentOS7系统服务管理systemctl

    目录 一.systemctl介绍 二.systemctl常用命令 1.启动服务 2.停止服务 3.重启服务 4.查看服务是否已启动 5.查看服务的状态 6.启用开机自启动服务 7.停用开机自启动服务 ...

  6. 还是只使用console.log()进行调试?好吧,其实还有更多。

    在浏览器控制台中打印消息无疑可以拯救所有开发人员. console.log()消息就像您的大多数疾病的药,同时调试了代码中的一些有线问题. 那里的大多数开发人员都喜欢— 让我们在浏览器中打印消息以了解 ...

  7. [模拟] Codefroces 1175B Catch Overflow!

    题目:http://codeforces.com/contest/1175/problem/B B. Catch Overflow! time limit per test 1 second memo ...

  8. 利用Python获取文件类型

    这里选择使用使用filetype获取文件的类型. 使用filetype之前,先用pip安装filetype. #!/usr/bin/python3 import filetype import arg ...

  9. OpenCV-Python 使用OCR手写数据集运行KNN | 五十四

    目标 在本章中 我们将使用我们在kNN上的知识来构建基本的OCR应用程序. 我们将尝试使用OpenCV自带的数字和字母数据集. 手写数字的OCR 我们的目标是构建一个可以读取手写数字的应用程序.为此, ...

  10. 基础英语(一):Unit1

    零,英语学习方法 我看了大量的学习方法,在其它科目都是很管用的,唯独英语,没有任何一个学习方法能够适合适用于我,但是我也从其他的学习方法中总结出了一些规律,那就是任何学习都是脱离不了例子的,任何事物都 ...