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. 关于python如何安装和配置chromedriver以及一些相关问题

    解决问题三部曲:观察,思考,尝试 1.如何配置chromedriver: https://www.cnblogs.com/lintest/p/11697059.html 常见异常解决的一个参考吧:ht ...

  2. 【简介】OpenOCD 由jtag操作到parport driver流程

    1. 定义 jtag_command_type 在 OpenOCD 中,JTag 命令在枚举 jtag_command_type 中定义,定义如下: /** * The type of the @c ...

  3. mysql事务原理及MVCC

    mysql事务原理及MVCC 事务是数据库最为重要的机制之一,凡是使用过数据库的人,都了解数据库的事务机制,也对ACID四个 基本特性如数家珍.但是聊起事务或者ACID的底层实现原理,往往言之不详,不 ...

  4. MySQL数据备份与恢复(二) -- xtrabackup工具

    上一篇介绍了逻辑备份工具mysqldump,本文将通过应用更为普遍的物理备份工具xtrabackup来演示数据备份及恢复的第二篇内容. 1.  xtrabackup 工具的安装 1.1  安装依赖包 ...

  5. 关于Quartz .NET(V3.0.7)的简要说明

    目录 0. 任务调度 1. Quartz .NET 1.1 基本概念 1.2 主要接口和对象 2. 使用示例 2.0 准备工作 2.1 每间隔一定时间间隔执行一次任务 2.3 某天的固定时间点执行任务 ...

  6. AI学习笔记:人工智能与机器学习概述

    一.人工智能基本概念 1.1 基本概念 数据分析:对历史规律的展现.对未来数据的预测. 机器学习:机器学习是指从一系列的原始数据中找到规律,提取人们可以识别的特征,然后通过学习这些特征,最终产生一个模 ...

  7. shell编程之循环语句

    for #! /bin/sh for FRUIT in apple banana pear; do echo "I like $FRUIT" done while #! /bin/ ...

  8. Servlet(四)----Request

    ##  Request 1.request对象和response对象的原理 1.request和response对象是由服务器创建的.我们来使用他们. 2.request对象是来获取请求消息,resp ...

  9. 升级 nop 4.1 Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.

    Incorrect syntax near 'OFFSET'.  Invalid usage of the option NEXT in the FETCH statement. nop.web 项目 ...

  10. 动态规划-Minimum Cost to Merge Stones

    2019-07-07 15:48:46 问题描述: 问题求解: 最初看到这个问题的时候第一反应就是这个题目和打破气球的题目很类似. 但是我尝试了使用dp将问题直接转为直接合并到一个堆问题复杂度迅速提高 ...