Action Sheet和Alert是2種特殊的控件(暫且稱之為控件吧,其實不是控件真正的控件,而是ios中的2個類,這2個類定義了2種不同類型的用於和用戶交互的彈出框),Action Sheet是從底部彈出,上面有2個或者2個以上的選項供用戶選擇,Alert就是一個警告框,上面有1個或者1個以上的按鈕供用戶進行選擇。
在繼續這一篇的內容之前,稍微花點時間說一下ios中用到的Delegate Pattern(委托\代理模式)。
ios中有很多已經定義好的類可以供我們在編寫程序時直接使用,例如UIActionSheet、UIAlertView等,這些類定義了很多method,我們可以調用這些method且不必知道這些method是如何實現的。但是有一個問題,如果我們想改變這些method的實現,那我們該這么做呢?一種方法是繼承,我們可以繼承一個類,然后在自己的類中重新寫method,這是一個方法,但不是一個很方便的方法,有時候你僅僅需要改變很小的一個功能,卻要繼承一個很大的類,貌似有點復雜了,而且如果你需要一些不同的實現,那你就需要定義好多不同的類,這會很麻煩。為了使開發過程更加的方便,ios使用了另一種方法來達到同樣的目的,就是使用delegate,我們使用一個已定義的類,然后使用委托\代理來改寫類中的method,程序在運行時,delegate發現你創建了某個類的實例且改寫了其中的method,這樣程序在運行時就不會去調用原有的實現(當然你也可以調用原有的實現),而是直接調用你寫的新的實現,從而達到自定義程序方法的目的。
上面的這個說法可能不夠清楚,我自己也覺得比較含糊,那就看下面的例子,來進一步說明如何使用ios中用到的Delegate。
我們繼續上一篇的項目,實現button的buttenPressed Action
1)添加<UIActionSheetDelegate>
我們需要在BIDViewController類中使用UIActionSheet,而使用UIActionSheet時我們需要實現其一個delegate(並不是所有的delegate方法都要實現,只要根據實際需求去實現某些method,這個例子中的UIAlertView就不需要實現任何的delegate),但是在BIDViewController類中並沒有這個delegate的實現,因此需要手動添加,而在BIDViewController.h中添加<UIActionSheetDelegate>,就是讓BIDViewController可以接收並響應UIActionSheet的代理事件。
打開BIDViewController.h,添加<UIActionSheetDelegate>
#import <UIKit/UIKit.h> @interface BIDViewController : UIViewController <UIActionSheetDelegate> @property (weak, nonatomic) IBOutlet UITextField *nameField; @property (weak, nonatomic) IBOutlet UITextField *numberField; ......
2)實現buttonPressed
打開BIDViewController.m,找到buttonPressed方法,添加如下代碼
- (IBAction)buttonPressed:(id)sender { UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:@"Are you sure?" delegate:self cancelButtonTitle:@"No Way!" destructiveButtonTitle:@"Yes, I'm Sure!" otherButtonTitles:nil]; [actionSheet showInView:self.view]; }
編譯運行,單擊“Do Something” button后,一個Action Sheet會從底部彈出,如下
ok,我們根據這個Action Sheet來分析下上面代碼中UIActionSheet中的每個參數的意思:
[UIActionSheet alloc]:分配內存空間
initWithTitle:@"Are you sure":ActionSheet的title
delegate:self:指明這個UIActionSheet的代理在哪里,self說明這個代理在本類中,也就是說在UIActionSheet所在的類中尋找UIActionSheet的代理方法的實現(這個例子中的類就是指類BIDViewController)。回過頭再去看BIDViewController.h中我們剛剛添加的<UIActionSheetDelegate>,讓該類可以接收並響應UIActionSheet的代理事件。
cancelButtonTitle:@"No Way!":取消按鈕,用於取消(不繼續進行下一步操作),這里設置取消按鈕的文字。
destructiveButtonTitle:@"Yes, I'm Sure!":相當於確定按鈕(繼續下一步操作),這里設置確定按鈕的文字。
otherButtonTitles:nil:除了上面的取消按鈕和確定按鈕外,ActionSheet還可以自定義多個按鈕,這里設置其他按鈕的文字(例如:otherButtonTitles:@"Foo", @"Bar", nil;最后一個參數一定要寫nil,表示結束)。
上面code中的最后一行:
[actionSheet showInView:self.view]
作用是顯示actionSheet,每一個ActionSheet都需要有一個parent view,在parent view中顯示自己,因為我們是單一視圖項目(Single View),也只有一個View,因此這里的self.view就是說在actionSheet實現的這個view里顯示。
3)實現actionSheet delegate方法
在BIDViewController.m中的buttonPressed方法下面添加如下code
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { if(buttonIndex != [actionSheet cancelButtonIndex]) { NSString *msg = nil; if(nameField.text.length > 0) msg = [[NSString alloc] initWithFormat:@"You can breathe easy, %@, everything went OK.", nameField.text]; else msg = @"You can breathe easy, everything went OK."; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Something was done" message:msg delegate:self cancelButtonTitle:@"Phew!" otherButtonTitles:nil]; [alert show]; } }
上面的code實現了一個Action Sheet的delegate:didDismissWithButtonIndex,當點擊actionSheet按鈕時,會調用到該delegate,而不會去調用其原有的方法。在該方法中,首先判斷用戶沒有點擊cancelButton(根據button的Index來判斷),如果確實沒有點擊cancelbutton(點擊了destructiveButton,因為只有2個button),就顯示一個警告框。
UIAlertView的參數說明:
[UIAlertView alloc]:分配內存空間
initWithTitle:@"Something was done":Alert的title
message:msg:Alert的文字
delegate:self:作用和ActionSheet中的類似,只是UIAlertView沒有實現任何delegate方法,因此我們也沒有在頭文件中引入<UIAlertViewDelegate>
cancelButtonTitle:@"Phew!":取消按鈕,可以看作是關閉Alert窗口的按鈕,然后什么操作都不繼續。
otherButtonTitles:nil:作用和ActionSheet中的一樣
總的來看,UIAlertView和UIActionSheet的實現相當類似,可以對比着進行學習。
4)編譯運行
點擊Do Something按鈕,顯示ActionSheet
點擊No Way!按鈕,ActionSheet消失,點擊Yes,I'm Sure!按鈕,ActionSheet消失,然后顯示一個警告框
如果在nameField中填寫一些內容,則Alert中會顯示
點擊Phew!按鈕,警告框消失。
這篇的內容可能對高手來說很容易,但是對剛剛入門的新手來說,可能會產生疑惑,至少我是學了比較長的時間,而且在網上找了很多資料慢慢理解,才稍微有點了解,望各位高手能夠提出寶貴意見,謝謝!