码迷,mamicode.com
首页 > 移动开发 > 详细

[iOS基础控件 - 4.5] 猜图游戏

时间:2014-11-28 06:12:19      阅读:465      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   使用   sp   

A.需要掌握的
1.添加图片资源(暂时认为@2x跟非@2x代表同一张图片)

2.搭建UI界面
* 文本标签
* 4个按钮
* 中间的图片

3.设置状态栏样式

4.监听下一题按钮的点击

5.延迟加载数据
* 加载plist
* 字典转模型
* KVC的引入

6.切换下一题的序号、图片、标题,下一题按钮的可用性

7.默认显示第1条题目

8.显示大图
* 监听中间图片点击
* 添加遮盖
* 移动图片(注意头像图片的层级顺序)
* 监听“大图按钮”

9.展示答案的个数

10.展示待选答案

11.答案处理

12.提示功能

13.Icon和Launch、@2x
 
B.实现思路
1.构建基本UI:
(1)背景
(2)按钮
(3)图片
(4)选项
 
2.数据存储与加载
(1)标题数据
(2)图片数据
(3)可选项数据
(4)答案数据
(5)得分数据
 
3.大图功能 (点击图片或者按钮)
(1)放大并调整图片位置
(2)虚化背景,使用半透明全覆盖的button
(3)点击背景或者图片,删除半透明背景、恢复图片
     a.动画效果, 使用带block参数方法
     b.播放完动画再移除阴影元素
 
4.下一题功能
其调用的功能是整个APP的核心,包含了初始化控件、加载文件数据、删除旧控件、加入新控件、刷新界面
 
5.提示功能
给出一定的答案
 
6.帮助功能
(在线分享功能,没有实现)
 
C.知识点
1.设置状态栏 (iOS7开始)
(1)设置样式
在Controller中重写preferredStateBarStyle方法,返回要设置的值
 1 // 设置状态栏是否隐藏
 2 - (BOOL)prefersStatusBarHidden {
 3     return NO;
 4 }
 5  
 6 // 设置状态栏
 7 - (UIStatusBarStyle)preferredStatusBarStyle {
 8     // 设置状态栏字体为白色
 9     return UIStatusBarStyleLightContent;
10 }
 
状态栏是显示黑色字体:
bubuko.com,布布扣
 
修改之后:
bubuko.com,布布扣
 
2.APP图标
只要文件名为 “Icon.png”,就会被设置为APP图标
 
3.启动画面
               一个app在启动过程中会全屏显示叫做Default.png的图片
               不用规格Default的使用场合
  1.      Default.png:非retina-iPhone屏幕,320x480
  2.          Default@2x.png:retina-iPhone屏幕,640x960
  3.          Default-568h@2x.png:4inch的retina-iPhone屏幕,640x1136
  4.          Default-Portrait~ipad.png:非retain-iPad竖屏屏幕,768x1024
  5.          Default-Portrait~ipad@2x.png:retain-iPad竖屏屏幕,1536x2048
  6.          Default-Landscape~ipad.png:非retain-iPad横屏屏幕,1024x768
  7.          Default-Landscape~ipad@2x.png:retain-iPad横屏屏幕,2048x1536
 
 
4.背景图和前景元素之间的层次关系
一般按照storyboard中的顺序排列
使用代码把某个元素提到最前
    // 2.更换阴影和图片的位置
    [self.view bringSubviewToFront:self.icon];
 
 
5.使用Button做出中间的图片
为了做出有白边效果的图片,使用了白色图片作为背景,然后设置图片的边距Inset,露出白色背景图
bubuko.com,布布扣                   bubuko.com,布布扣
 
 
6.延迟加载数据
改写controller中的题目数组questions 的get方法,在调用get方法的时候检测questions是否已经存在,否则才开始加载
 
7.“大图”功能
虚化背景:使用一张半透明的图片遮挡
图片放大:使用形变转换
动画效果:使用带block参数的动画方法,设置动画事件、完成动画后消除遮盖回收内存
bubuko.com,布布扣
 
8.恢复图片
点击遮盖 / 点击放大后的图片:消除遮盖,恢复图片
 
9.消除button被点击的时候变灰
取消勾选 “Highlighted Adjusts Image”
bubuko.com,布布扣
 
10.显示答案
使用button, 动态生成相应数量的button
使用UIView作为父控件包含多个答案button
在storyboard中创建一个UIView,放到合适位置,调整尺寸
bubuko.com,布布扣
 
点击 "下一题” 按钮:
删除旧答案,自己控制自己从父视图删除
1     // 5.1 删除全部旧答案的button
2     [self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
 
添加新答案
bubuko.com,布布扣
 
 
11.加入选项
原理同答案模块,多了在行上面的位置计算
bubuko.com,布布扣
 
删除旧的所有选项,添加新的选项
1     // 6.1 删除旧选项
2     [self.optionsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
 
12.点击选项
(1)被点击的选项按钮消失(hidden = YES)
(2)将选中选项的文字放到答案区的按钮上
(3)把文字放到第一个没有文字的答案按钮上
(4)点击有文字的答案按钮,文字恢复到选项
(5)答案填满后,阻止事件触发
bubuko.com,布布扣
 
13.点击有文字的答案按钮
(1)被点击的答案按钮文字消失
(2)让答案文字对应的选项重新出现
遍历所有选项,找到对应的选项进行设置
bubuko.com,布布扣
 
14.判断答案正确
(1)遍历答案区,判断每个答案按钮是否有文字,如果都有文字,证明已经完成,检查答案
(2)答错答案文字变红,退选答案恢复文字颜色为黑色
(3)答对了给出提示,延迟1秒后跳入下一题
bubuko.com,布布扣
 
17.分数计算
答对加分
bubuko.com,布布扣
 
18.提示功能
取消现有的所有答案,给出正确答案的第一个字,扣一定分数
bubuko.com,布布扣
 
 
19.更改图标
图标有命名规范,最好使用 “icon.png"
把所有图标文件拖放到 “Images.xcassets” 的”AppIcon” 里面
bubuko.com,布布扣
 
bubuko.com,布布扣
 
20.修改启动画面
 
注意:
在现时最新版Xcode6.1中,默认使用 LaunchScreen.xib 作为启动画面
现在有两种方式设置启动图片
  • 使用 xib (LaunchScreen)
  • 使用 LaunchImage
 
启动页面配置:
项目 ==> general ==> App Icons and Launch Images
(1)使用 xib
a.默认状态就是使用 xib
bubuko.com,布布扣
 
b.如果现状态是使用LaunchImage, 设置 “Launch Images Source” 为 “Don’t use asset catalogs”
bubuko.com,布布扣
 
c.设置 xib 的文件名
bubuko.com,布布扣
 
d.在 xib 中设计
bubuko.com,布布扣
 
e.效果
bubuko.com,布布扣
 
 
(2)使用 LaunchImage
a.更改配置
项目 ==> general ==> App Icons and Launch Images ==> Launch Images Source 中选择 images,再把Launch Screen File 选项设置为空
bubuko.com,布布扣
 
 
b.会发现Images.xcassets 下自动生成了一个 LaunchImage 的Imageset
bubuko.com,布布扣
 
c.拖入画面
bubuko.com,布布扣
 
d.效果
bubuko.com,布布扣
 
 
主要代码:
ViewController.m:
  1 //
  2 //  ViewController.m
  3 //  CrazyGuessGame
  4 //
  5 //  Created by hellovoidworld on 14/11/26.
  6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
  7 //
  8 
  9 #import "ViewController.h"
 10 #import "Question.h"
 11 
 12 @interface ViewController ()
 13 
 14 @property (weak, nonatomic) IBOutlet UILabel *noLabel; // 序号
 15 @property (weak, nonatomic) IBOutlet UILabel *titleLabel; // 标题
 16 @property (weak, nonatomic) IBOutlet UIButton *icon;
 17 @property (weak, nonatomic) IBOutlet UIButton *nextImageButton;
 18 @property (weak, nonatomic) IBOutlet UIView *answerView;
 19 @property (weak, nonatomic) IBOutlet UIView *optionsView;
 20 @property (weak, nonatomic) IBOutlet UIButton *scoreButton;
 21 
 22 - (IBAction)onTipsButtonClicked;
 23 - (IBAction)onHelpButtonClicked;
 24 - (IBAction)onEnlargeImgButtonClicked;
 25 - (IBAction)onNextImgButtonClicked;
 26 - (IBAction)onImageClicked;
 27 
 28 /** 所有题目 */
 29 @property(nonatomic, strong) NSArray *questions;
 30 
 31 /** 当前题目序号 */
 32 @property(nonatomic, assign) int index;
 33 
 34 /** 遮盖阴影 */
 35 @property(nonatomic, weak) UIButton *cover;
 36 
 37 /** 原始图片位置、尺寸 */
 38 @property(nonatomic, assign) CGRect imageOriginalFrame;
 39 
 40 /** 答案是否已经填满标识 */
 41 @property(nonatomic, assign) BOOL isAnswerCompleted;
 42 
 43 /** 得分 */
 44 @property(nonatomic, assign) int score;
 45 
 46 @end
 47 
 48 @implementation ViewController
 49 
 50 - (void)viewDidLoad {
 51     [super viewDidLoad];
 52     // Do any additional setup after loading the view, typically from a nib.
 53    
 54     //存储原始图片的位置、尺寸信息
 55     self.imageOriginalFrame = self.icon.frame;
 56    
 57     self.index = -1;
 58     [self onNextImgButtonClicked]; // 初次加载,index是0
 59 }
 60 
 61 - (void)didReceiveMemoryWarning {
 62     [super didReceiveMemoryWarning];
 63     // Dispose of any resources that can be recreated.
 64 }
 65 
 66 // 改写getter, 延迟加载,此处不要使用self.questions来取得questions,否则陷入死循环
 67 - (NSArray *)questions {
 68     if (nil == _questions) {
 69         // 1.加载plist数据
 70         NSArray *questionDictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"questions" ofType:@"plist"]];
 71        
 72         NSMutableArray *questionsArray = [NSMutableArray array];
 73         for (NSDictionary *questionDict in questionDictArray) {
 74             // 2.将数据封装到Model "Question"
 75             Question *question = [Question initWithDictionary:questionDict];
 76             [questionsArray addObject:question];
 77         }
 78 
 79         // 3.赋值
 80         _questions = questionsArray;
 81     }
 82    
 83     return _questions;
 84 }
 85 
 86 // 设置状态栏是否隐藏
 87 - (BOOL)prefersStatusBarHidden {
 88     return NO;
 89 }
 90 
 91 
 92 // 设置状态栏
 93 - (UIStatusBarStyle)preferredStatusBarStyle {
 94     // 设置状态栏字体为白色
 95     return UIStatusBarStyleLightContent;
 96 }
 97 
 98 
 99 // 点击“提示”按钮
100 - (IBAction)onTipsButtonClicked {
101     // 1.清除现有的答案
102     for (UIButton *currentAnswerButton in self.answerView.subviews) {
103         [self onAnswerClicked:currentAnswerButton];
104     }
105    
106     // 2.取出正确答案片段
107     Question *question = self.questions[self.index];
108     NSString *partOfCorrectAnswer = [question.answer substringToIndex:1];
109    
110     // 3.填充到答案区
111     for (UIButton *optionButton in self.optionsView.subviews) {
112         if ([partOfCorrectAnswer isEqualToString:optionButton.currentTitle]) {
113             [self onOptionClicked:optionButton];
114         }
115     }
116    
117     // 5.扣取相应分数
118     [self calScore:-500];
119 }
120 
121 // 点击“帮助”按钮
122 - (IBAction)onHelpButtonClicked {
123 }
124 
125 // 点击“大图”按钮
126 - (IBAction)onEnlargeImgButtonClicked {
127     // 1.1添加阴影
128     UIButton *cover = [[UIButton alloc] init];
129     cover.frame = self.view.bounds;
130     cover.backgroundColor = [UIColor blackColor];
131     cover.alpha = 0;
132    
133     // 1.2给阴影添加变回小图的触发事件
134     [cover addTarget:self action:@selector(smallImg) forControlEvents:UIControlEventTouchUpInside];
135    
136     self.cover = cover;
137     [self.view addSubview:cover];
138    
139     // 2.更换阴影和图片的位置
140     [self.view bringSubviewToFront:self.icon];
141    
142     // 3.更改图像大小,显示阴影
143     [UIView animateWithDuration:1 animations:^{
144         cover.alpha = 0.7;
145        
146         CGFloat iconWidth = self.view.frame.size.width;
147         CGFloat iconHeight = iconWidth;
148         CGFloat iconX = 0;
149         CGFloat iconY = (self.view.frame.size.height / 2) - (iconHeight / 2);
150         self.icon.frame = CGRectMake(iconX, iconY, iconWidth, iconHeight);
151     }];
152 }
153 
154 /** 缩小图片 */
155 - (void) smallImg {
156     [UIView animateWithDuration:1 animations:^{
157         // 1.删除阴影
158         self.cover.alpha = 0;
159        
160         // 2.恢复图片
161         self.icon.frame = self.imageOriginalFrame;
162        
163     } completion:^(BOOL finished) {
164         // 动画执行完成后
165        
166         [self.cover removeFromSuperview];
167         self.cover = nil;
168     }];
169    
170 }
171 
172 // 点击“下一题”按钮
173 - (IBAction)onNextImgButtonClicked {
174     self.index++;
175    
176     // 1.取出相应地Model数据
177     Question *question = self.questions[self.index];
178 
179     // 2.设置控件
180     [self setControls:question];
181    
182     // 3.设置答案
183     [self addAnswer:question];
184    
185     // 4.设置选项
186     [self addOptions:question];
187    
188 
189 }
190 
191 /** 设置控件 */
192 - (void) setControls:(Question *) question {
193     // 1.答案是否已经填满
194     self.isAnswerCompleted = NO;
195    
196     // 2.得分
197     [self.scoreButton setTitle:[NSString stringWithFormat:@"%d", self.score] forState:UIControlStateNormal];
198    
199     // 2.设置序号
200     self.noLabel.text = [NSString stringWithFormat:@"%d/%d", self.index + 1, self.questions.count];
201    
202     // 3.设置标题
203     self.titleLabel.text = question.title;
204    
205     // 4.设置图片
206     [self.icon setImage:[UIImage imageNamed:question.icon] forState:UIControlStateNormal];
207    
208     // 5.设置“下一题”按钮
209     self.nextImageButton.enabled = (self.index + 1) != self.questions.count;
210 }
211 
212 /** 加入答案区 */
213 - (void) addAnswer:(Question *) question {
214     // 5.1 删除全部旧答案的button
215     [self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
216    
217     // 5.1 加入新答案
218     int answerCount = question.answer.length; // 答案字数
219    
220     // 初始化尺寸信息
221     CGFloat answerWidth = 35;
222     CGFloat answerHeight = self.answerView.frame.size.height;
223     CGFloat answerMargin = 10;
224     CGFloat answerMarginLeft = (self.answerView.frame.size.width - answerWidth * answerCount - answerMargin * (answerCount - 1) ) / 2;
225    
226     for (int i=0; i<question.answer.length; i++) {
227         // 计算位置
228         CGFloat answerX = answerMarginLeft + i * (answerWidth + answerMargin);
229         CGFloat answerY = 0;
230        
231         UIButton *answerButton = [[UIButton alloc] initWithFrame:CGRectMake(answerX, answerY, answerWidth, answerHeight)];
232        
233         // 设置背景
234         [answerButton setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState: UIControlStateNormal];
235         [answerButton setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState: UIControlStateHighlighted];
236        
237         // 设置按钮点击事件,让按钮文字消失,相应的选项恢复
238         [answerButton addTarget:self action:@selector(onAnswerClicked:) forControlEvents:UIControlEventTouchUpInside];
239        
240         [self.answerView addSubview:answerButton];
241     }
242    
243     [self.view addSubview:self.answerView];
244 }
245 
246 /**
247     设置按钮点击事件,让按钮文字消失,相应的选项恢复
248 */
249 - (void) onAnswerClicked:(UIButton *) answerButton {
250     // 1.设置答案标识
251     self.isAnswerCompleted = NO;
252    
253     // 2.恢复相应的选项
254     NSString *answerTitle = [answerButton titleForState:UIControlStateNormal];
255     for (UIButton *optionButton in self.optionsView.subviews) {
256         if ([answerTitle isEqualToString:[optionButton titleForState:UIControlStateNormal]]
257             && optionButton.isHidden) {
258             optionButton.hidden = NO;
259             break;
260         }
261     }
262    
263     // 3.清除按钮上的文字
264     [answerButton setTitle:nil forState:UIControlStateNormal];
265    
266     // 4.恢复答案文字颜色
267     for (UIButton *answerButton in self.answerView.subviews) {
268         [answerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
269     }
270 }
271 
272 /** 加入选项区 */
273 - (void) addOptions:(Question *) question {
274     // 6.1 删除旧选项
275     [self.optionsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
276    
277     // 6.2 加入新选项
278     int optionsCount = question.options.count;
279     CGFloat optionWidth = 35;
280     CGFloat optionHeight = 35;
281     int columnCount = 7;
282     CGFloat optionMargin = 10;
283     CGFloat optionMarginLeft = (self.optionsView.frame.size.width - optionWidth * columnCount - optionMargin * (columnCount - 1)) / 2;
284    
285     for (int i=0; i<optionsCount; i++) {
286         int rowNo = i / columnCount; // 当前行号,从0开始
287         int columnNo = i % columnCount; // 当前列号,从0开始
288         CGFloat optionX = optionMarginLeft + columnNo * (optionWidth + optionMargin);
289         CGFloat optionY = rowNo * (optionHeight + optionMargin);
290        
291         UIButton *optionButton = [[UIButton alloc] initWithFrame:CGRectMake(optionX, optionY, optionWidth, optionHeight)];
292        
293         [optionButton setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
294         [optionButton setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted];
295        
296         [optionButton setTitle:question.options[i] forState:UIControlStateNormal];
297        
298         [optionButton addTarget:self action:@selector(onOptionClicked:) forControlEvents:UIControlEventTouchUpInside];
299        
300         [self.optionsView addSubview:optionButton];
301     }
302    
303     [self.view addSubview:self.optionsView];
304 }
305 
306 // 使点击到的选项消失 
307 - (void) onOptionClicked:(UIButton *) optionButton {
308     // 1.如果答案尚未填满,使选中的选项消失
309     if (self.isAnswerCompleted) {
310         return;
311     }
312    
313     optionButton.hidden = YES;
314    
315     // 2.使消失的文字出现在答案区上,判断是否已经完成
316     NSString *optionTitle = [optionButton titleForState:UIControlStateNormal];
317    
318     // 遍历答案按钮
319     for (int i=0; i<self.answerView.subviews.count; i++) {
320         // 已经遍历到了最后一个答案按钮,证明已经完成了所有答案
321         if (i == self.answerView.subviews.count - 1) {
322             self.isAnswerCompleted = YES;
323         }
324        
325         UIButton *answerButton = self.answerView.subviews[i];
326         NSString *answerTitle = [answerButton titleForState:UIControlStateNormal];
327        
328         // 如果该答案按钮上没有文字,则是空,填入文字
329         if (answerTitle.length == 0) {
330             // 按钮默认的字体颜色是白色, 手动设为黑色
331             [answerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
332             [answerButton setTitle:optionTitle forState:UIControlStateNormal];
333            
334             break;
335         }
336     }
337    
338     [self dealWithAnswer];
339 }
340 
341 /** 处理答案 */
342 - (void) dealWithAnswer {
343     if (self.isAnswerCompleted) {
344         Question *question = self.questions[self.index];
345         NSMutableString *answerStr = [NSMutableString string];
346        
347         // 拼接已经完成的答案
348         for (UIButton *completedAnswerButton in self.answerView.subviews) {
349             [answerStr appendString:[completedAnswerButton titleForState:UIControlStateNormal]];
350         }
351        
352         // 如果答对了
353         if ([answerStr isEqualToString:question.answer]) {
354             // 答案字体转换称为蓝色
355             for (UIButton *correctAnswerButton in self.answerView.subviews) {
356                 [correctAnswerButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
357             }
358            
359             // 延迟指定时间后跳入下一题
360             [self performSelector:@selector(onNextImgButtonClicked) withObject:nil afterDelay:0.5];
361            
362             // 加分
363             [self calScore:1000];
364         }
365         else {
366             for (UIButton *correctAnswerButton in self.answerView.subviews) {
367                 // 答案字体转换称为红色
368                 [correctAnswerButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
369             }
370         }
371     }
372 }
373 
374 /** 原图状态点击放大,大图状态点击恢复原状 */
375 - (IBAction)onImageClicked {
376     // 使用遮盖是否存在判断图片状态
377    
378     // 1.遮盖不存在,放大图片
379     if (nil == self.cover) {
380         [self onEnlargeImgButtonClicked];
381     }
382     else {
383     // 2.遮盖存在,恢复图片
384         [self smallImg];
385     }
386 }
387 
388 /** 计算分数 */
389 - (void) calScore:(int) score {
390     self.score += score;
391     [self.scoreButton setTitle:[NSString stringWithFormat:@"%d", self.score] forState:UIControlStateNormal];
392 }
393 
394 @end
 
Question.h:
 1 //
 2 //  Question.h
 3 //  CrazyGuessGame
 4 //
 5 //  Created by hellovoidworld on 14/11/26.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface Question : NSObject
12 
13 @property(nonatomic, copy) NSString *answer;
14 @property(nonatomic, copy) NSString *title;
15 @property(nonatomic, copy) NSString *icon;
16 @property(nonatomic, strong) NSArray *options;
17 
18 - (instancetype) initWithDictionary:(NSDictionary *) dictionary;
19 + (instancetype) initWithDictionary:(NSDictionary *) dictionary;
20 
21 @end
 
Question.m
 1 //
 2 //  Question.m
 3 //  CrazyGuessGame
 4 //
 5 //  Created by hellovoidworld on 14/11/26.
 6 //  Copyright (c) 2014年 hellovoidworld. All rights reserved.
 7 //
 8 
 9 #import "Question.h"
10 
11 @implementation Question
12 
13 - (instancetype) initWithDictionary:(NSDictionary *) dictionary {
14     if (self = [super init]) {
15         self.title = dictionary[@"title"];
16         self.icon = dictionary[@"icon"];
17         self.answer = dictionary[@"answer"];
18         self.options = dictionary[@"options"];
19     }
20    
21     return self;
22 }
23 
24 + (instancetype) initWithDictionary:(NSDictionary *) dictionary {
25     return [[self alloc] initWithDictionary:dictionary];
26 }
27 
28 @end
 
 

[iOS基础控件 - 4.5] 猜图游戏

标签:style   blog   http   io   ar   color   os   使用   sp   

原文地址:http://www.cnblogs.com/hellovoidworld/p/4127572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!