三十而立,從零開始學ios開發(七):Delegate,Action Sheet, Alert


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!按鈕,警告框消失。

 

這篇的內容可能對高手來說很容易,但是對剛剛入門的新手來說,可能會產生疑惑,至少我是學了比較長的時間,而且在網上找了很多資料慢慢理解,才稍微有點了解,望各位高手能夠提出寶貴意見,謝謝!

 

 

Control Fun All

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM