欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > 内容正文

疯狂猜图实例实现,猜图实例

来源: 开发者 投稿于  被查看 7506 次 评论:247

疯狂猜图实例实现,猜图实例


疯狂猜图实例实现

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

注意:
*   按钮的Inset属性使用技巧实现边框效果
*   
如何一次性修改多个控件的共同属性
*   
金币按钮的文字对齐方式的细节处理
*   
禁止金币按钮的交互
*   用代码修改状态栏的显示

二、编写代码
1图片的放大缩小处理
#pragma mark - 大图小图切换
- (
IBAction)bigImage
{
   
// 如果没有放大,就放大,否则就缩小
   
// 通过蒙板的alpha来判断按钮是否已经被放大
   
if (self.cover.alpha == 0.0) { // 放大
       
// 2. 将图像按钮弄到最前面
       
// bringSubviewToFront将子视图前置
        [
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.0f 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;
        }];
    }
}

注意: 放大图片      (1增加遮罩
     (
2将图像移动至顶层
     [
self.view bringSubviewToFront:self.iconButton];
     (
3动画放大图像,同时增加遮罩的透明度

缩小图片
     (1增加遮罩按钮的监听方法
     (
2块动画缩小图像按钮,恢复位置
     (
3动画结束后,删除遮罩

问题:每次点击时,遮罩都会重复被创建
解决方法:建立遮罩的属性,并通过懒加载的方式创建
- (UIButton *)cover
{
   
if (_cover == nil) {
       
_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;
}

2> 下一题
#pragma mark - 下一题
- (
IBAction)nextQuestion
{
   
// 1. 当前答题的索引,索引递增
   
self.index++;
   
// 如果index已经到最后一题,提示用户,播放动画,音乐.....
   
if (self.index == self.questions.count) {
       
NSLog(@"通关了");
       
return;
    }
   
// 2. 从数组中按照索引取出题目模型数据
   
HMQuestion *question = self.questions[self.index];
   
// 3. 设置基本信息
    [
self setupBasicInfo:question];
   
// 4. 设置答案按钮
    [
self createAnswerButtons:question];
   
// 5. 设置备选按钮
    [
self createOptionButtons:question];
}

/** 设置基本信息 */
- (
void)setupBasicInfo:(HMQuestion *)question
{
   
self.noLabel.text = [NSString stringWithFormat:@"%d/%d", self.index + 1, self.questions.count];
   
self.titleLabel.text = question.title;
    [
self.iconButton setImage:question.image forState:UIControlStateNormal];
   
// 如果到达最后一题,禁用下一题按钮
   
self.nextQuestionButton.enabled = (self.index < self.questions.count - 1);
}

/** 创建答案区按钮 */
- (
void)createAnswerButtons:(HMQuestion *)question
{
   
// 首先清除掉答题区内的所有按钮
   
// 所有的控件都继承自UIView,多态的应用
   
for (UIView *btn in self.answerView.subviews) {
        [btn
removeFromSuperview];
    }
   
CGFloat answerW = self.answerView.bounds.size.width;
   
int length = question.answer.length;
   
CGFloat answerX = (answerW - kButtonWidth * length - kButtonMargin * (length - 1)) * 0.5;
   
   
// 创建所有答案的按钮
   
for (int i = 0; i < length; i++) {
       
CGFloat x = answerX + i * (kButtonMargin + kButtonWidth);
       
       
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, kButtonWidth, kButtonHeight)];
        [btn
setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal];
        [btn
setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState:UIControlStateHighlighted];
       
       
// 设置标题颜色
        [btn
setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
       
        [
self.answerView addSubview:btn];
        [btn
addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside];
    }
}

/** 创建备选区按钮 */
- (
void)createOptionButtons:(HMQuestion *)question
{
   
// 问题:每次调用下一题方法时,都会重新创建21个按钮
   
// 解决:如果按钮已经存在,并且是21个,只需要更改按钮标题即可
   
if (self.optionsView.subviews.count != question.options.count) {
       
// 重新创建所有按钮
       
for (UIView *view in self.optionsView.subviews) {
            [view
removeFromSuperview];
        }
       
       
CGFloat optionW = self.optionsView.bounds.size.width;
       
CGFloat optionX = (optionW - kTotolCol * kButtonWidth - (kTotolCol - 1) * kButtonMargin) * 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 * (kButtonMargin + kButtonHeight);
           
           
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, kButtonWidth, kButtonHeight)];
            [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];
        }
       
NSLog(@"创建候选按钮");
    }
   
   
// 如果按钮已经存在,在点击下一题的时候,只需要设置标题即可
   
int i = 0;
   
for (UIButton *btn in self.optionsView.subviews) {
       
// 设置备选答案
        [btn
setTitle:question.options[i++] forState:UIControlStateNormal];
       
       
// 回复所有按钮的隐藏状态
        btn.
hidden = NO;
    }
}

思路: (1题目索引递增
(
2取出题目模型
(
3设置题目基本信息(图片、标签等)
(
4设置答案按钮
(
5设置备选按钮


注意: 问题:到达最后一题时出现数组越界
解决方法:重新连线并传递参数,如果到达最后一题,禁用按钮

3> 备选按钮的点击,让文字进入答案区
#pragma mark - 候选按钮点击方法
- (
void)optionClick:(UIButton *)button
{
   
// 1. 在答案区找到第一个文字为空的按钮
   
UIButton *btn = [self firstAnswerButton];
   
   
// 如果没有找到按钮=>所有的"答题按钮都有字",直接返回
   
if (btn == nil) {
       
// 都有字判断胜负
    }
else {
       
// 2. button的标题设置给答案区的按钮
        [btn
setTitle:button.currentTitle forState:UIControlStateNormal];
       
       
// 3. button隐藏
        button.
hidden = YES;
    }
   
// 4. 判断结果
    [
self judge];
}

4> 判断胜负
*
胜利:进入下一题
*
失败:提示用户重新选择
- (
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(@"都有字");
       
// 判断是否和答案一致
       
// 根据self.index获得当前的question
       
HMQuestion *question = self.questions[self.index];
       
       
// 如果一致,进入下一题
       
if ([strM isEqualToString:question.answer]) {
           
NSLog(@"答对了");
            [
self setAnswerButtonsColor:[UIColor blueColor]];
           
           
// 增加分数
            [
self changeScore:800];
           
           
// 等待0.5秒,进入下一题
            [
self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5];
        }
else {
           
// 如果不一致,修改按钮文字颜色,提示用户
           
NSLog(@"答错了");
            [
self setAnswerButtonsColor:[UIColor redColor]];
        }
    }
}

5> 答题按钮的点击
把答案区的文字回复到备选区域
/** 修改答题区按钮的颜色 */
- (
void)setAnswerButtonsColor:(UIColor *)color
{
   
for (UIButton *btn in self.answerView.subviews) {
        [btn
setTitleColor:color forState:UIControlStateNormal];
    }
}

// 在答案区找到第一个文字为空的按钮
- (
UIButton *)firstAnswerButton
{
   
// 取按钮的标题
   
// 遍历答题区所有按钮
   
for (UIButton *btn in self.answerView.subviews) {
       
if (btn.currentTitle.length == 0) {
           
return btn;
        }
    }
   
return nil;
}

#pragma mark - 答题区按钮点击方法
- (void)answerClick:(UIButton *)button
{
   
// 1. 如果按钮没有字,直接返回
   
if (button.currentTitle.length == 0) return;
   
   
// 2. 如果有字,清除文字,候选区按钮显示
   
// 1> 使用buttontitle去查找候选区中对应的按钮
   
UIButton *btn = [self optionButtonWithTilte:button.currentTitle isHidden:YES];
   
   
// 2> 显示对应按钮
    btn.
hidden = NO;
   
   
// 3> 清除button的文字
    [button
setTitle:@"" forState:UIControlStateNormal];
   
   
// 4> 只要点击了按钮上的文字,意味着答题区的内容不完整
    [
self setAnswerButtonsColor:[UIColor blackColor]];
}

- (
UIButton *)optionButtonWithTilte:(NSString *)title isHidden:(BOOL)isHidden
{
   
// 遍历候选区中的所有按钮
   
for (UIButton *btn in self.optionsView.subviews) {
       
if ([btn.currentTitle isEqualToString:title] && btn.isHidden == isHidden) {
           
return btn;
        }
    }
   
return nil;
}
 
6> 提示功能

#pragma mark - 提示功能
- (IBAction)tipClick
{
   
// 1. 把答题区中所有的按钮清空
   
for (UIButton *btn in self.answerView.subviews) {
       
// 用代码执行点击答题按钮的操作
        [
self answerClick:btn];
    }
   
   
// 2. 把正确答案的第一个字,设置到答题区中
   
// 1> 知道答案的第一个字
   
HMQuestion *question = self.questions[self.index];
   
// 月光宝盒
   
NSString *first = [question.answer substringToIndex:1];
   
// 取出文字对应的候选按钮
   
UIButton *btn = [self optionButtonWithTilte:first isHidden:NO];
    [
self optionClick:btn]; 
   
// 扣分
    [
self changeScore:-1000];
}

7> 分数处理
#pragma mark - 分数处理
- (void)changeScore:(int)score
{
   
// 取出当前的分数
   
int currentScore = self.scoreButton.currentTitle.intValue;
   
   
// 使用score调整分数
    currentScore += score;
   
   
// 重新设置分数
    [
self.scoreButton setTitle:[NSString stringWithFormat:@"%d", currentScore] forState:UIControlStateNormal];
}


8> 收尾工作:图标和启动图片

注意: 问题:第一次点击时,整个页面灰蒙蒙的,后面就好了?
问题原因:由于遮罩是懒加载的,将图片按钮移动到顶层之后,才会被创建
解决方法:先调用一次getter方法

相关文章

    暂无相关文章
相关频道:

相关阅读

    用户评论