標籤:idt 第一個 ons 事件 cts boa btn ddc orm
案例效果:
(1)匯入所需的素材,然後用storyboard把上半截位置和大小相對固定的東西布局起來。當然,這些控制項也要定義成對應地IBOutlet和IBAction方便興許使用它們。
注意:本案例在3.5inch裝置上顯示最佳,所以須要設定一下。
(2)首先實現點擊“下一題”的功能
- (IBAction)nextQuestion { //1、序號添加 self.index++; //2、依據序號拿到相應的模型(對象) NSQuestion *question=self.questions[self.index]; //3、設定文本以及映像 self.noLabel.text=[NSString stringWithFormat:@"%d/%d",self.index+1,self.questions.count]; self.titleLabel.text=question.title; [self.iconBtn setImage:[UIImage imageNamed:question.icon] forState:UIControlStateNormal]; //4、推斷button是否失效 self.nextQuestionBtn.enabled=self.index!=(self.questions.count-1); //5、加入正確答案 [self addAnswerBtn:question]; //6、加入option選項 [self addOptionBtn:question];}
當然,在viewLoad中要讓視圖顯示第一個頁面,須要例如以下:
- (void)viewDidLoad { self.index=-1; [self nextQuestion]; [super viewDidLoad];}
然後一個個實現nextQuestion方法中提到的那些方法。
(3)定義一個資料模型類,就是將字典轉化成模型
在NSQuestion.h中:
#import <Foundation/Foundation.h>@interface NSQuestion : NSObject@property(nonatomic,copy) NSString *answer;@property(nonatomic,copy) NSString *title;@property(nonatomic,copy) NSString *icon;@property(nonatomic,strong) NSArray *options;-(instancetype)initWithDic:(NSDictionary *)dict;+(instancetype)questionWithDic:(NSDictionary *)dict;@end
在NSQuestion.m中:
#import "NSQuestion.h"@implementation NSQuestion-(instancetype)initWithDic:(NSDictionary *)dict{ if ([super init]) { self.answer=dict[@"answer"]; self.title=dict[@"title"]; self.icon=dict[@"icon"]; self.options=dict[@"options"]; } return self;}+(instancetype)questionWithDic:(NSDictionary *)dict{ return [[self alloc]initWithDic:dict];}@end
在ViewController.m中轉化成模型:
#import "ViewController.h"#import "NSQuestion.h"@interface ViewController ()@property(nonatomic,strong) NSArray *questions;@end@implementation ViewController-(NSArray *)questions{ if (_questions==nil) { NSArray *arr1=[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"questions.plist" ofType:nil]]; NSMutableArray *questionArray=[[NSMutableArray alloc]init]; for (NSDictionary *dic1 in arr1) { NSQuestion *question=[[NSQuestion alloc]initWithDic:dic1]; [questionArray addObject:question]; } _questions=questionArray; } return _questions;}
(4)addAnswerBtn方法
-(void)addAnswerBtn:(NSQuestion *)question{ //5、加入正確答案 //先刪除上一題的answer //讓數組中的全部對象都運行相同地方法。用以下這一句取代以下的for迴圈 [self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];// for (UIView *subViews in self.answerView.subviews) {// [subViews removeFromSuperview];// } //然後再加入新的answer,依據答案的長度來加入 int length=question.answer.length; for (int i=0; i<length; i++) { UIButton *answerBtn=[[UIButton alloc]init]; [answerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];//設定文字顏色,否則預設白色於背景相同 [answerBtn setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal]; [answerBtn setBackgroundImage:[UIImage imageNamed:@"btn_answer_highlighted"] forState:UIControlStateHighlighted]; CGFloat answerMargin=10; CGFloat answerW=35; CGFloat answerH=35; CGFloat answerX=(self.view.frame.size.width-length*answerW-(length-1)*answerMargin)/2+i*(answerW+answerMargin); answerBtn.frame=CGRectMake(answerX, 0, answerW, answerH); [self.answerView addSubview:answerBtn]; //監聽點擊事件 [answerBtn addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside]; }}
這個點擊事件的方法:
-(void)answerClick:(UIButton *)answerBtn{ //讓答案button文字相應的button顯示出來,用for遍曆 //擷取button文字用currentTitle// NSString *answerTitle=[answerBtn titleForState:UIControlStateNormal]; for (UIButton *optionBtn in self.optionView.subviews) {// NSString *optionTitle=[optionBtn titleForState:UIControlStateNormal]; //推斷哪個optionbutton再顯示出來。並且這個button本身是隱藏的,由於option裡可能有同樣的文字 if ([answerBtn.currentTitle isEqualToString:optionBtn.currentTitle] && optionBtn.hidden==YES) { optionBtn.hidden=NO; break; } } //點擊的button文字消失,由於這個文字上面須要用到比較,所以比較晚,再把文字去除 [answerBtn setTitle:nil forState:UIControlStateNormal]; //點擊隨意一個button。相當於去除文字,那麼答案就不是正確答案,文字顏色回複黑色 for (UIButton *answerBtn in self.answerView.subviews) { [answerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; }}
(4)addOptionBtn方法
-(void)addOptionBtn:(NSQuestion *)question{ //6、加入option選項 //也是先刪除再加入,相同用一句取代for迴圈 [self.optionView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];// for (UIView *subViews in self.optionView.subviews) {// [subViews removeFromSuperview];// } int count=question.options.count; int totalColumn=7; for (int i=0; i<count; i++) { UIButton *optionBtn=[[UIButton alloc]init]; [optionBtn setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal]; [optionBtn setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted]; CGFloat optionMargin=10; CGFloat optionW=35; CGFloat optionH=35; int row=i/7; int col=i%7; CGFloat optionX=(self.view.frame.size.width-totalColumn*optionW-(totalColumn-1)*optionMargin)/2+col*(optionW+optionMargin); CGFloat optionY=row*(optionH+optionMargin); optionBtn.frame=CGRectMake(optionX, optionY, optionW, optionH); [optionBtn setTitle:question.options[i] forState:UIControlStateNormal]; [optionBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [self.optionView addSubview:optionBtn]; //button點擊 [optionBtn addTarget:self action:@selector(optionClick:) forControlEvents:UIControlEventTouchUpInside]; }}
這個監聽事件方法:
-(void)optionClick:(UIButton *)optionBtn{ //1、被點擊的button消失 optionBtn.hidden=YES;//不能刪除,由於還要顯示,所以用隱藏 //2、顯示文字到正確答案上去(第一個沒有文字的answerbutton) //這裡設定完,無法查看效果,是由於answer的文字預設是白色,於背景同樣 for (UIButton *answerBtn in self.answerView.subviews) { //推斷是否有文字// NSString *answerTitle=[answerBtn titleForState:UIControlStateNormal]; if (answerBtn.currentTitle.length==0) { [answerBtn setTitle:[optionBtn titleForState:UIControlStateNormal] forState:UIControlStateNormal]; break;//找到後就通知for的遍曆 } } //每點擊一個optionbutton就推斷這個答案是否已經填滿,並推斷是否正確 BOOL full=YES; NSMutableString *tempAnswerTitle=[NSMutableString string]; for (UIButton *answerBtn in self.answerView.subviews){// NSString *answerTitle=[answerBtn titleForState:UIControlStateNormal]; if (answerBtn.currentTitle.length==0) {//說明答案沒有滿 full=NO; } //拼接文字 if (answerBtn.currentTitle) { [tempAnswerTitle appendString:answerBtn.currentTitle]; } } //假設答案滿了,則推斷是否正確 if (full) { NSQuestion *question=self.questions[self.index]; if ([tempAnswerTitle isEqualToString:question.answer]) { for (UIButton *answerBtn in self.answerView.subviews) { [answerBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; } //推斷正確後 //先拿到當前分,再加分 [self addScore:100];// int score=[self.scoreBtn titleForState:UIControlStateNormal].intValue;// score+=100;// [self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal]; //延遲運行:跳到下一題 //直接用[self nextQuestion];會馬上跳轉 [self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5]; }else{ for (UIButton *answerBtn in self.answerView.subviews) { [answerBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; } } }}
這裡面用到一個addScore計算分數的方法:
-(void)addScore:(int)dealtScore{ int score=[self.scoreBtn titleForState:UIControlStateNormal].intValue; score+=dealtScore; [self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal];}
(5)對應的,點擊“提示”產生的效果,是清空answer。給第一個字,並扣分
- (IBAction)tip { //1、先清空answer。也就是點擊answer的button。就相當於清空 for (UIButton *answerBtn in self.answerView.subviews) { [self answerClick:answerBtn]; } //2、取出正確答案 NSQuestion *question=self.questions[self.index]; //3、取出正確答案的第一個字元 NSString *firstAnswer=[question.answer substringToIndex:1]; //4、推斷並從option中取出 for (UIButton *optionBtn in self.optionView.subviews) { if ([optionBtn.currentTitle isEqualToString:firstAnswer]) { [self optionClick:optionBtn]; break; } } //5、扣分 [self addScore:-500];// int score=[self.scoreBtn titleForState:UIControlStateNormal].intValue;// score-=500;// [self.scoreBtn setTitle:[NSString stringWithFormat:@"%d",score] forState:UIControlStateNormal];}
(6)點擊“大圖”的效果。加入一個陰影,調整映像順序。並讓圖片和陰影等動畫變動
- (IBAction)bigImg { //1、加入一個半透明陰影 UIButton *cover=[[UIButton alloc]init]; cover.frame=self.view.bounds; cover.backgroundColor=[UIColor blackColor]; cover.alpha=0; [cover addTarget:self action:@selector(smallImg) forControlEvents:UIControlEventTouchUpInside]; self.cover=cover; [self.view addSubview:cover]; //2、調整陰影和映像順序 [self.view bringSubviewToFront:self.iconBtn]; //相同。用block改造以下的代碼 [UIView animateWithDuration:0.5 animations:^{ cover.alpha=0.7;//陰影逐步出現 //3、改變映像大小frame CGFloat iconW=self.view.frame.size.width; CGFloat iconH=iconW; CGFloat iconY=(self.view.frame.size.height-iconH)/2; self.iconBtn.frame=CGRectMake(0, iconY, iconW, iconH); }]; // [UIView beginAnimations:nil context:nil];// cover.alpha=0.7;//陰影逐步出現// //3、改變映像大小frame// CGFloat iconW=self.view.frame.size.width;// CGFloat iconH=iconW;// CGFloat iconY=(self.view.frame.size.height-iconH)/2;// self.iconBtn.frame=CGRectMake(0, iconY, iconW, iconH);// [UIView commitAnimations];}
上述代碼中得陰影cover有一個事件,就是點擊後圖片恢複小圖,而且陰影消失等等。例如以下:
-(void)smallImg{ //用block動畫改造以下代碼以及removeCover方法 [UIView animateWithDuration:0.5 animations:^{ self.cover.alpha=0;//先讓陰影逐漸消失,然後刪除 self.iconBtn.frame=CGRectMake(85, 86, 150, 150); } completion:^(BOOL finished) { [self.cover removeFromSuperview]; self.cover=nil;//便於推斷陰影是否還存在 }]; // //1、刪除陰影//// //2、映像位置恢複frame// [UIView beginAnimations:nil context:nil];// //動畫結束後,調用self的removeCover方法刪除陰影,這樣刪除陰影才會有個延遲,陰影逐漸消失的動畫才幹正常// [UIView setAnimationDelegate:self];// [UIView setAnimationDidStopSelector:@selector(removeCover)];// self.cover.alpha=0;//先讓陰影逐漸消失,然後刪除// self.iconBtn.frame=CGRectMake(85, 86, 150, 150);//也能夠在變大之前記錄原有位置// [UIView commitAnimations];}//-(void)removeCover{// [self.cover removeFromSuperview];// self.cover=nil;//便於推斷陰影是否還存在//}
(7)而點擊圖片本身,也會有放大縮小的事件:
- (IBAction)iconClick { if (self.cover==nil) { [self bigImg]; }else{ [self smallImg]; }}
(8)用到的知識點
——擷取button當前文字用.currentTitle屬性。
——實現動畫特效,除了[UIView beginAnimations:]這套組合外,推薦使用[UIView animateWithDuration: animations:^{ } completion:^(BOOL finished) { }];假設動畫完畢後沒有須要啟動並執行代碼。那麼最後面的completion能夠去除。
——調整子視圖上下疊加順序能夠用bringSubviewToFront之類的方法。
——注意,button的文字預設是白色,假設背景也是白色,那麼須要格外注意。
——假設圖片的frame屬性設定沒有生效,即沒有變大縮小移動等特效。那麼通常是Auto Layout沒有關閉。
——button有一個預設屬性:按下時顏色變暗,假設不須要,則取消勾選“Highlighted Adjusts Image”。
——截取某字串的前某幾個字元則用substringToIndex。數字是N,則是0~n-1這幾個字元。
——實現透明度,是屬性alpha。
——一般要刪除某個控制項,則須要這個控制項自身調用removeFromSuperview方法。
但假設要刪除某個視圖裡面的非常多子視圖,除了用for迴圈讓子視圖一個個自己自刪,還能夠用例如以下方法:makeObjectsPerformSelector。
[self.answerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];// for (UIView *subViews in self.answerView.subviews) {// [subViews removeFromSuperview];// }——一般我們假設刪除某個控制項,在刪除後,把這個控制項設定為nil。而不想刪除。僅僅是隱藏,後面還須要再顯示,則用控制項的hidden屬性。
——注意代碼順序。比方用button上得文字和其它button上的文字相比較,然後在刪除這個button,這是正確順序,而不能先刪除,否則後面無法擷取到這個button上得文字。
——推斷button有沒有文字:推斷button文字的長度是否等於0。
——可變字串的加入用appendString方法。
——延遲運行某個動作能夠用performSelector:@selector() withObject:nil afterDelay:這種方法。
假設是[self perform...]那麼就是延遲運行self的selector裡的方法。
——把一個字串轉換成整型,能夠直接在這個字串後面添加.intValue屬性。
(9)怎樣加入icon表徵圖(iPhone的、AppStore以及spotlight的,當然興許還有ipad的等等)
直接按要求定義好圖片大小和命名規範。然後拖到Image.xcassets的AppIcon裡就可以。
(10)怎樣加入啟動頁面?
直接在LaunchScreen.xib裡面設定。這個和玩storyboard一樣樣的。
我們此處設定的大小是3.5inch的。所以設定好裝置尺寸後。把原先的刪除掉,直接弄一個imageView。在上面加入個圖片就可以。
【iOS開發-51】案例學習:動畫新寫法、刪除子視圖、視圖順序、延遲方法、button多功能使用方法及icon表徵圖和啟動頁設定