day04-超级猜图
来源:互联网 发布:泰山学院网络管理系统 编辑:程序博客网 时间:2024/05/16 06:05
前言
视图不能交互的几种情况
1./**视图不能交互的几种情况:1.视图的属性 1》 [[UIButton alloc] init].alpha <= 0.01 2》[[UIButton alloc] init].hidden= YES 3》[[UIButton alloc] init].userInteractionEnabled =NO; UIImageView /UILabel 的userInteractionEnabled 属性默认为NO2. 若父视图不允许交互,则子视图也是一样不能交互 3.位于父视图的不可见范围的子视图部分 是不能交互的(可以使用clip subviews 属性进行验证);即只有在父视图可见范围才可以交互 */- (IBAction)click { /** 1.Oc风格BOOL 具有 YES 和 NO。实用8位存储空间。从最低位算起。 YES定义为1,NO定义为0。 2.控制台输出布尔值 NSLog(@"ifReadOnly value: %@" ,ifReadOnly?@"YES":@"NO"); */ NSLog(@"%d",([[UIImageView alloc]init].userInteractionEnabled ? YES: NO));//@property (nonatomic, getter=isUserInteractionEnabled) BOOL userInteractionEnabled; // default is NO NSLog(@"%d",([[UIButton alloc] init].userInteractionEnabled? YES: NO));//1}2.// UIView.userInteractionEnabled属性@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled; // default is YES. if set to NO, user events (touch, keys) are ignored and removed from the event queue.,但 UIImageView /UILabel 的userInteractionEnabled 属性默认为NO
掌握:
一、按钮的多功能使用
图层(蒙板、或者说遮罩)的操作--蒙板通常是UIButton对象
二、@2x的含义
1、Retina 屏幕
1》对点和像素的理解
提交App Store的时候记得上传这类图标1024x1024 App list in iTunes on devices with retina display
四、数组乱序的实现
//// ViewController.m// 02-for//// Created by devzkn on 3/12/16.// Copyright © 2016 hisun. All rights reserved.//#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //使用块代码实现数组排序和乱序 // 数组不能存储nil,因为OC是采用nil 来判断数组是否结束--Collection element of type 'void *' is not an Objective-C object NSArray *array = @[@(1),@(4),@(5),@(2)];//快速包装NSNumber类型数组 for (NSNumber *number in array) { NSLog(@"%@",number); } array = [array sortedArrayUsingComparator:^NSComparisonResult(NSNumber *number1, NSNumber *number2) { //乱序-->一会升序,一会乱序 //随机 int seed = arc4random_uniform(2);//0-1 之间的随机数 if (seed) {//1 YES 被定义为1 return [number2 compare:number1]; } return [number1 compare:number2]; }]; NSLog(@"%@",array);}/** sortedArrayUsingComparator 块代码数组排序 */- (NSArray *) sortedArrayUsingComparator: (NSArray *)array{ //0 . 数组排序Returns an array that lists the receiving array’s elements in ascending order, as determined by the comparison method specified by a given NSComparator Block. //1> 返回参数typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending}; array = [array sortedArrayUsingComparator:^NSComparisonResult(NSNumber *number1, NSNumber *number2) { //比较方法(规则) /** 2016-03-12 11:46:04.539 02-for[1880:51443] nimber1= 1 ;number2= 4 2016-03-12 11:46:04.539 02-for[1880:51443] nimber1= 5 ;number2= 2 2016-03-12 11:46:04.540 02-for[1880:51443] nimber1= 4 ;number2= 5 2016-03-12 11:46:04.540 02-for[1880:51443] nimber1= 4 ;number2= 2 2016-03-12 11:46:04.540 02-for[1880:51443] nimber1= 1 ;number2= 2 1 4 5 2->4 1 5 2 ->4 1 5 2 ->5 4 1 2 -> 5 4 1 2 -> 5 4 2 1 */ NSLog(@"nimber1= %@ ;number2= %@",number1,number2); return [number2 compare:number1];//NSOrderedAscending if the value of aNumber is greater than the number object’s, NSOrderedSame if they’re equal, and NSOrderedDescending if the value of aNumber is less than the number object’s. 返回数组元素的比较结果 }]; NSLog(@"%@",array); return array;}/** 块代码遍历数组 */- (void)arrayWith: (NSArray *)array { //1》 数组的遍历Executes a given block using each object in the array, starting with the first object and continuing through the array to the last object. //2>obj The element in the array.对象 idx The index of the element in the array. 索引 stop A reference to a Boolean value. The block can set the value to YES to stop further processing of the array. The stop argument is an out-only argument. You should only ever set this Boolean to YES within the Block.是否中断 //3 > 块数组的遍历方法效率比 for in 方式来的高 [array enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) { NSLog(@"%@ idx= %lu",obj,idx); if (1 == idx) { *stop = YES;//退出循环 } }];}@end
五、主要方法,尽量保留简洁代码,体现思路和流程即可
ps:p s:0>xcode 的快捷键:option+command+left(代码折叠)、
1> 模拟器的快捷键 :切换屏幕 shift+command+h(显示主界面)、shift+command+h+h(结束程序)
六、等待一段时间,再让线程调用方法的例子
1》 延迟进入下一题-》目的是给玩家展示绿色答案文字//等待0.5秒,直接进入下一题Invokes a method of the receiver on the current thread using the default mode after a delay. [self updateAnswerButtonTitleColor:[UIColor greenColor]];//动画显示答案字体为绿色 [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:1.0];//2》 动画结束要清空UIImageView 对象的属性AnimationImages,即设置其为nil //清除内存的代码简化--可以避免定义cleanUpAnimationsArray方法,直接调用setAnimationImages方法进行arrayImage的清除 [self.imageList performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:self.imageList.animationDuration];//- (void)cleanUpAnimationsArray{// NSLog(@"%s ",__func__);// //动画结束之后清除帧动画数组// [self.imageList setAnimationImages:nil];////}
七、 实现方法的时候,考虑执行该方法的条件
//1.再定义方法时,首先考虑的一个问题是:先判断是否达到执行该方法的资格(条件),否则直接return//1》答案区的点击事件#pragma mark - 答题按钮的监听方法,若答案按钮标题的空的,没必要执行本方法/** 处理答题按钮点击事件 */- (void) answerButtonClick:(UIButton *) answerButton{ //1.如果当前答案按钮没有标题,直接return if (nil == answerButton.currentTitle) { return; }//2》 候选区的点击事件,若答案区都是满的,就没必要执行该方法#pragma mark - 候选按钮点击方法;- (void)optionButtonClick:(UIButton *)button{ //1.找到答案区的第一个没有标题的按钮 UIButton *nilTitleButton = [self firstNilTitleAnswerButton]; if (nil == nilTitleButton) {//找不到空标题按钮,return return; }
八、字符串对象是否为空的判断
//1.对象比较的效率 比数值型比较效率低//1>效率好些的空字符串对象判断: if (0 == answerButton.currentTitle.length) { return; }//2>效率低: if (nil == nilTitleButton) {//找不到空标题按钮,return return; }
正文
疯狂猜图案例的需求分析
Click here to expand…疯狂猜图案例的需求分析
1.搭建界面
1》上半部分空间位置固定的,使用storyBoard进行布局连线
2》下半部分的控件,是根据题目的变化而变化-》采用代码方式进行界面搭建
2.编写代码(按照流程进行实现,即用户的操作习惯流程)
1》大图小图的切换
2》下一题的实现
3》备选按钮点击事件处理(让文字进入答案区)
4》判断胜负:胜利,界面切换到下一题;失败,提示用户重新选择答案
5》答题按钮点击事件的处理:把答案区的文字恢复到备选区域
3.收尾工作
图标和启动页面
总结
OC 解决NSArray直接打印中文出现乱码的问题?
解决方法:就是需要通过为NSArray添加分类,重写 - (NSString *)descriptionWithLocale:(id)locale方法即可
附
控制器的代码实现
//// ViewController.m// 01-超级猜图//// Created by devzkn on 3/9/16.// Copyright © 2016 devzkn. All rights reserved.//#import "ViewController.h"#import "HSQuestion.h"#define KButtonWidth 35#define KButtonSpacingWidth 10 // 按钮的行间距#define KButtonSpacingHeight 5 //按钮的列间距#define KButtonHeight 35//九宫格算法 x 决定的是其所在的列,y 决定其所在的行#define KButtonColumn 7 //列数#define KButtonRow 3//行数@interface ViewController ()@property (weak, nonatomic) IBOutlet UIButton *iconButton;//图像按钮@property (nonatomic,weak) UIButton *cover;//蒙板@property (nonatomic,strong) NSArray *questions;//问题数组@property (nonatomic,assign) int index;//当前题目index@property (weak, nonatomic) IBOutlet UILabel *noLabel;@property (weak, nonatomic) IBOutlet UILabel *titleLabel;@property (weak, nonatomic) IBOutlet UIButton *nextButton;@property (weak, nonatomic) IBOutlet UIView *answerView;@property (weak, nonatomic) IBOutlet UIView *optionsView;@property (weak, nonatomic) IBOutlet UIButton *coinButton;//金币按钮@end@implementation ViewController/** 懒加载questions */- (NSArray *) questions{ if (nil == _questions) { _questions = [HSQuestion questionList]; } return _questions;}/** 懒加载蒙板按钮控件 */- (UIButton *)cover{ if (nil == _cover){ //创建蒙板 UIButton *tmpCover = [[UIButton alloc]initWithFrame:self.view.bounds]; [tmpCover setBackgroundColor: [UIColor colorWithWhite:0.0 alpha:0.5]]; [tmpCover setAlpha:0.0]; //添加conver图层的监听事件 [tmpCover addTarget:self action:@selector(smallerIconButton) forControlEvents:UIControlEventTouchUpInside]; _cover=tmpCover; [self.view addSubview:_cover];//cover强引用+1 } return _cover;}- (void)viewDidLoad { [super viewDidLoad]; //上半部分的界面控件基本是静态的,采用storyBoard进行实现 //搭建下半部分的界面,采用代码实现 //初始化界面 [self nextQuestion];}/** he preferred status bar style for the view controller.调整状态栏颜色 */- (UIStatusBarStyle)preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED{// Defaults to UIStatusBarStyleDefault return UIStatusBarStyleLightContent;}/** pecifies whether the view controller prefers the status bar to be hidden or shown. 重写方法 */- (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED{ return NO;//A Boolean value of YES specifies the status bar should be hidden. Default value is NO.}/** 大图小图切换 */#pragma mark - 大图小图切换--pragma 是预处理命令- (IBAction)biggerSmallerIconButton { //判断当前的图像按钮是否处于放大状态,如果是就进行缩小,否则进行放大; //判断依据为蒙板cover的Alpha属性值 if (1.0 == self.cover.alpha) {// Alpha: 1.0 放大状态,0.0 缩小状态 [self smallerIconButton]; return ; } [self biggerImage];}#pragma mark - 下一题的实现/** 下一题 1.在主要方法中,尽量保留简短代码,体现思路和流程即可 */- (IBAction)nextQuestion{ //如果题号大于等于总题数 ,直接return,即只有题号self.index为“0-题目总数” 的时候才执行本方法 if (self.questions.count <= self.index || 0 >self.index) { return; } //下一题,在数据模型中是数据递增的关系 //1> 当前答题的index递增 self.index = (self.index <self.questions.count) ? self.index+1 :self.index; //禁用next Button 的判断,(在题目序号递增之后判断)// [self.nextButton setEnabled: (self.index >=self.questions.count || self.index < 0 ) ? NO : YES];//当前题目序号大于或者等于题目总数,以及小于0 就禁用,否则就启用 [self.nextButton setEnabled:(self.index>0 && self.index < self.questions.count)];//当题号》0且题号小于总题数,就启用nextbutton按钮,否则禁用button //2> 根据题目index从数据模型数组取出question对象(题目数据) HSQuestion *question = self.questions [self.index-1];//当前题目的数据模型在数组中的index=当前题目的index-1 // 3> 通过建立连线获得基本信息控件;修改题目的基本信息(iconImage、title 以及题目的index控件) [self setupBasicInfo:question]; //4>答案区按钮设置,根据答案的文字个数进行布局 [self createAnswerButtons:question]; //5>创建备选按钮 [self createOptionButtons:question];}/** 设置基本信息 */- (void)setupBasicInfo:(HSQuestion *)question{ //设置iconImage [self.iconButton setImage:question.iconImage forState:UIControlStateNormal]; //设置title控件 [self.titleLabel setText:[NSString stringWithFormat: @"%@",question.title]]; //设置题目的index [self.noLabel setText:[NSString stringWithFormat:@"%d/%lu",self.index,self.questions.count]];}/** 创建答案区按钮 */- (void)createAnswerButtons: (HSQuestion *)question{ //清空上一题的答案按钮 for (UIView *button in [self.answerView subviews]) {//使用的UIbutton 都继承于UIView [button removeFromSuperview];//多态的应用 } //布局答案区,类似九宫格 //根据答案文字个数往视图添加按钮 // 获取问题答案的个数 long answerNo = question.answer.length; //第一个button的x值 CGFloat answerX =(CGRectGetWidth(self.answerView.frame)- answerNo*KButtonWidth-(answerNo-1)*KButtonSpacingWidth)*0.5 ; for (int i= 0; i<answerNo; i++) { CGFloat x = answerX + i*(KButtonWidth+KButtonSpacingWidth); UIButton *answerButton = [[UIButton alloc]initWithFrame:CGRectMake(x, 0, KButtonWidth, KButtonHeight)]; [answerButton setBackgroundColor:[UIColor whiteColor]]; [answerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //设置背景图片 [answerButton setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal]; [answerButton setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState:UIControlStateHighlighted]; //设置按钮的监听方法 [answerButton addTarget:self action:@selector(answerButtonClick:) forControlEvents:UIControlEventTouchUpInside]; [self.answerView addSubview:answerButton]; }}/** 创建候选区按钮, */- (void)createOptionButtons:(HSQuestion *)question{ //1》如果已经存在候选按钮,就直接修改按钮标题,不用在创建候选按钮 NSArray *subviewsArray = [self.optionsView subviews]; if (subviewsArray.count >= question.options.count) { //获取按钮文字 for (int i=0 ;i<subviewsArray.count;i++) { [subviewsArray[i] setTitle:question.options[i] forState:UIControlStateNormal]; //设置按钮为可见 [subviewsArray[i] setHidden:NO]; } return;//设置完标题直接结束方法 } //2》创建候选按钮 // 设置候选区按钮显示内容(用模型数据装配),根据候选文字总数 进行布局,并使用乱序算法进行装配按钮控件// // 清空上一题候选按钮(清除optionsView的所有子视图) for (UIView *view in [self.optionsView subviews]) { [view removeFromSuperview]; } //根据列数、行数 的个数 进行候选区的的布局(九宫格) //定义行第一列的buttonX值 CGFloat optionMarginX = (CGRectGetWidth(self.optionsView.frame)-KButtonColumn*KButtonWidth -(KButtonColumn-1)*KButtonSpacingWidth)*0.5; CGFloat optionMarginY = (CGRectGetHeight(self.optionsView.frame)- KButtonRow*KButtonHeight-(KButtonRow-1)*KButtonSpacingHeight)*0.5; //对候选答案进行乱序可在数据模型HSQuestion questionList方法中实现 //布局候选按钮,并装配数据 for (int i =0 ; i<question.options.count; i++) { //创建候选按钮 int columnNo = i%KButtonColumn ;//button 所在的列 int rowNo = i/KButtonColumn;//button 所在的行数 //计算button 的x,y CGFloat x = optionMarginX +columnNo*(KButtonWidth+KButtonSpacingWidth);//x 值与列数相关 CGFloat y = optionMarginY+rowNo*(KButtonHeight+KButtonSpacingHeight);//y值与行数关联 UIButton *optionButton = [[UIButton alloc] initWithFrame:CGRectMake(x, y, KButtonWidth, KButtonHeight)]; [optionButton setBackgroundColor:[UIColor whiteColor]]; //设置候选答案文字 [optionButton setTitle:question.options[i] forState:UIControlStateNormal]; //设置按钮文字font [optionButton.titleLabel setFont:[UIFont systemFontOfSize:12]]; //设置文字颜色 [optionButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; //设置按钮的背景图片 [optionButton setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal]; [optionButton setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted]; //设置候选按钮的监听方法 [optionButton addTarget:self action:@selector(optionButtonClick:) forControlEvents:UIControlEventTouchUpInside]; [self.optionsView addSubview:optionButton]; }}#pragma mark - 候选按钮点击方法- (void)optionButtonClick:(UIButton *)button{ //1.找到答案区的第一个没有标题的按钮 UIButton *nilTitleButton = [self firstNilTitleAnswerButton]; if (nil == nilTitleButton) {//找不到空标题按钮,return return; } //找到了空标题按钮的操作: //2.将按钮标题设置到答题区视图的第一个空标题按钮中 [nilTitleButton setTitle:button.titleLabel.text forState:UIControlStateNormal]; [button setHidden:YES]; //将按钮设置为不可见 //3.判断胜负(如果答案区的按钮均非空,即可进行答案判断) [self judge];}/** 判断结果,并提示玩家 */-(void)judge{ //1> 判断用户是否填写完问题,填完整了,才需要判断结果,否则return NSArray *array = [self.answerView subviews]; //用户填写答案 NSMutableString *userAnswer = [[NSMutableString alloc]init]; for (UIButton *btn in array) { if (btn.currentTitle.length == 0) {//如果有一个空为空,直接return return ; } [userAnswer appendString:btn.currentTitle]; } //2> 获取问题答案,进行比对,如果错误,就在答案区提示玩家,否则直接进入下一题 //获取正确答案 HSQuestion *question = self.questions[self.index-1];//当前题号-1 即使其所在数组对应的下标 if ([question.answer isEqualToString:userAnswer]) { [self updateAnswerButtonTitleColor:[UIColor greenColor]];//动画显示答案字体为绿色 //分数奖励 [self changeScore:500]; //等待0.5秒,直接进入下一题Invokes a method of the receiver on the current thread using the default mode after a delay. [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:1.0]; return; } //3>提示玩家重新选择,将答题按钮文字颜色改为红色 [self updateAnswerButtonTitleColor:[UIColor redColor]];}/** 修改答题区按钮的颜色 */- (void) updateAnswerButtonTitleColor:(UIColor *)color{ [UIView animateWithDuration:10.0f animations:^{ for (UIButton *answerButton in [self.answerView subviews]) { [answerButton setTitleColor:color forState:UIControlStateNormal]; } }];}#pragma mark - 答题按钮的监听方法/** 处理答题按钮点击事件 */- (void) answerButtonClick:(UIButton *) answerButton{ //1.如果当前答案按钮没有标题,直接return if (0 == answerButton.currentTitle.length) { return; } //2.执行此方法,意味着用户去除掉了一个字(即答题区的内容不完整),此时应将答案区的文字颜色恢复成黑色 [self updateAnswerButtonTitleColor:[UIColor blackColor]]; //3.设置与“当前按钮的”相同标题的候选区按钮为可见(执行到这里按理都会有存在这样的候选按钮) [[self optionButtonWithTitle:answerButton.currentTitle isHidden:YES] setHidden:NO ]; //移除当前按钮的标题 [answerButton setTitle:nil forState:UIControlStateNormal];}/** 根据title查找候选区按钮,特殊要求(规则,目标按钮的Hidden属性为YES 或者为NO) */- (UIButton *) optionButtonWithTitle:(NSString *)title isHidden:(BOOL)isHidden{ //考虑候选区有重复标题按钮的问题,增加Hidden属性的判断,只有为YES才是“答案按钮点击功能”要找的目标按钮;只有为NO的按钮才是“提示功能”要找的目标 for (UIButton *optionButton in [self.optionsView subviews]) { if ([title isEqualToString:optionButton.currentTitle] && (optionButton.hidden == isHidden)) { return optionButton; } } return nil;}/** 查找文字为空的按钮 */- (UIButton *)firstNilTitleAnswerButton{ NSArray *answerButtonArray =[self.answerView subviews]; for (UIButton *button in answerButtonArray) { //找出没有标题的按钮 if (0 == button.currentTitle.length ) {//这个判断方法比使用nil 进行判断的效率更高 return button; } } return nil;}/** 放大图片 */- (void)biggerImage { //0>biggerSmallerIconButton 保证将图像按钮bringSubviewToFront之前,cover的已经创建完成 //1》将图像按钮添加至最顶层 Moves the specified subview so that it appears on top of its siblings. [self.view bringSubviewToFront:self.iconButton]; //2》用块动画放大图像按钮 CGFloat width = CGRectGetWidth(self.view.frame); CGFloat height = width; CGFloat x=0; CGFloat y= (CGRectGetHeight(self.view.frame)- height)*0.5; //块动画 [UIView animateWithDuration:1.0f animations:^{ //动画内容:修改图像按钮大小、位置以及cover的透明度 [self.iconButton setFrame:CGRectMake(x, y, width, height)]; [self.cover setAlpha:1.0]; }];}/** 将图像按钮恢复原来大小 */- (void) smallerIconButton{ //使用块动画恢复icon Button的大小和位置,块动画是预先准备好的代码,一旦定义,将立即执行 [UIView animateWithDuration:1.0f animations:^{ [self.iconButton setFrame:CGRectMake(85, 85, 150, 150)]; [self.cover setAlpha:0.0];//将cover按钮控件设为不可见 }]; //设置图像按钮的放大、缩小状态 [self.iconButton setTag:0];}#pragma mark - 提示功能/** 1.提示功能的实现(用代码代替用户的按钮点击行为) 2. 提示功能,是要进行扣分,即执行该功能你必须达到消费的积分额度 */- (IBAction) tip{ if (self.coinButton.currentTitle.intValue <500) {//金币数小于本次消费的金币额度,直接结束 return; } //1.清空答案区的title并恢复候选按钮 [self cleanAnswerButtons]; // 2.取出正确答案的第一个字,并设置到都一个答案按钮,并隐藏候选区对应的按钮 //获取当前题目模型对象 HSQuestion *question =self.questions[self.index-1]; //获取与“正确答案第一个字母”相同标题候选按钮 UIButton *optionButton = [self optionButtonWithTitle:[question.answer substringToIndex:1] isHidden:NO]; //设置标题到答案区,并隐藏候选区按钮 [self optionButtonClick:optionButton]; //进行分数的扣减 [self changeScore:-500];}/** 清空答案区按钮,并恢复候选按钮 */- (void) cleanAnswerButtons{ for (UIButton *btn in [self.answerView subviews]) { //直接调用答案按钮的监听方法 [self answerButtonClick:btn];// }}#pragma mark - 分数处理/** 分数处理 */- (void) changeScore:(int) score{ score += self.coinButton.currentTitle.intValue ; [self.coinButton setTitle: [NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal];}@end
- day04-超级猜图
- iOS开发脚踏实地学习day04-超级猜图
- ios-day04-01(猜图游戏)
- day04
- Day04
- day04
- day04
- day04
- day04
- day04
- day04
- day04
- day04
- day04
- day04
- day04
- day04
- Day04
- POJ 2976 Dropping tests 【二分:最大化平均值】
- Map.Entry类
- ubuntu下文件的压缩&解压缩
- 数据库概念和操作数据库的命令
- SpringBoot启用log4j日志
- day04-超级猜图
- EC2部署IIS网站
- Java监听器Listener使用说明
- 选择排序
- android自动化测试总体说明
- LitePal源码解析——数据库的创建
- fiddler4使用教程解读
- 重写jquery的ajax,解决ie缓存
- java通用分页代码