Objective-C的頁面?zhèn)髦?/h2>

第一篇Objective的文章,第一次使用Markdown來寫。


頁面?zhèn)髦档姆椒ㄓ泻芏啵埠艹S玫?,Delegate/NSNotification/Block/NSUserDefault/單例,等等。
一項一項增加,先寫最常用的委托傳值,也就是Delegate,老師講的方法。(TryAttack,這個無聊的時候玩這個。)


委托傳值 Delegate

協(xié)議方法是一種非常常用的傳值方法,只要在協(xié)議中聲明一個協(xié)議方法,然后兩個類一個作為委托方一個作為遵守方來調(diào)用和實現(xiàn)方法就可以實現(xiàn)傳值。十分高效而且針對性很強(qiáng)。

我們建立完Text Field元件和程式碼的關(guān)聯(lián)后,完成頁面1UIViewControllerButton 拖拽到 SecndViewController ,並且在Custom Class 的Class中設(shè)定第二個ViewController 為 SecndViewController (即客制化所對應(yīng)的Class)。這樣就產(chǎn)生了 Storyboard Segue 的方法,選者Model作為連接,Storyboard Segue 就會自動連接到UIViewController。
如果想要使用不同的換頁效果,可以在 Storyboard Segue 中的 Transition 屬性做修改。
接下來我們就來實作委托傳值的方法,首先來考慮如何往 SecndViewController 進(jìn)行傳值。

  1. 透過 Storyboard Segue 傳值,在頁面 2SecndViewController 的 UIViewController class 里設(shè)置一個 NSString 的變數(shù),它用來接收由頁面 1 透過 Storyboard Segue 所傳過來的值,程式碼如下。
     @property (strong) NSString* strAttackPower;

之后在SecndViewController.hviewDidLoad函式里我們將 string 的值指定給 pAttackResult,此時頁面 2 加載時就會把 pAttackResult的內(nèi)容設(shè)成 Storyboard Segue 所傳送過來的值。

     - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        int iDefensValue = rand()%10;
        iScore = [strAttackPower intValue] - iDefensValue;
        if ( iScore > 0 ){
            pAttackResult.text = [NSString stringWithFormat: @"攻擊造成%d傷害,得分%d", iScore, iScore];
        }else {
            pAttackResult.text = @"攻擊被防御";
            iScore = 0;
        }
     }

接著回到頁面 1 的 UIViewController class 里,新增一個內(nèi)建的函式 prepareForSegue,至此我們完成透過 Storyboard Segue 傳值的方法。

     -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        id pNextPage = segue.destinationViewController;
        [pNextPage setValue:[NSString stringWithFormat: @"%d", 1+rand()%10 ] forKey: @"strAttackPower"];
        [pNextPage setValue:self forKey:@"delegate"];
     }

ViewController 切換(Segue)之前會呼叫上面的方法,至此我們完成了向下一層的傳值。

  • 關(guān)鍵點(diǎn)在 setValue: forKey: 下面看一下定義:
    setValue: forKey:

setValue: forKey:中value能夠為nil,但是當(dāng)value為nil的時候,會自動調(diào)用 removeObject: forKey:方法,key的參數(shù)只能夠是NSString類型,而對應(yīng)的 setObject: forKey: 的可以是任何類型

2.返回先前頁面的方法
使用 dismissModalViewControllerAnimated: 方法,或是 dismissViewControllerAnimated:completion: 方法來解散SecndViewController,并返回先前的頁面。

     - (IBAction)goBack:(id)sender {
        if ([self.delegate respondsToSelector:@selector(incrementScore:from:)]) {
            [self.delegate incrementScore:iScore from:self];
        }
        [self dismissViewControllerAnimated:YES completion: ^{}];
     }

3.由上面的兩步我們已經(jīng)建立兩個可以互相切換的 UIViewController,一個是透過 Storyboard Segue 來切換并且向下傳值,另一個則是使用 dismissViewControllerAnimated: 的方法來返回先前的 UIViewController。
接下來就是要解決的就是 SecndViewController 向上傳值的部分,也就是通過代理委托delegate,建立一個協(xié)定 @protocol 的方式。

將此分為兩個角色五個步驟。
委托者:
1.聲明delegate屬性。2.調(diào)用協(xié)議方法。
被委托者:
1.遵守協(xié)議。2.設(shè)定為被委托者。3.覆寫協(xié)議方法。

委托者 SecndViewController
1.聲明delegate屬性:首先在頁面 2 的 UIViewController class,建立一個協(xié)定 incrementScoreDelegate,并且定義其內(nèi)部的方法 goBack:,接著宣告一個采用此協(xié)定的物件 delegate,其程式碼如下。

     
     //建立一個協(xié)定
     @protocol incrementScoreDelegate;
     @interface SecndViewController : UIViewController
     @property (strong, nonatomic) IBOutlet UITextField *pAttackResult;
     @property (strong) NSString* strAttackPower;
     //協(xié)定中的方法
     @property (weak) id<incrementScoreDelegate> delegate;
      - (IBAction)goBack:(id)sender;
     @end
     //宣告一個採用incrementScoreDelegate 協(xié)定的物件 
     @protocol incrementScoreDelegate <NSObject>
      - (void) incrementScore: (int) score from:(SecndViewController* ) page;
     @end

2.調(diào)用協(xié)議方法: 也就是上面第二點(diǎn)2.返回先前頁面的方法,要呼叫協(xié)定必須寫在按鈕事件中。當(dāng)我們按下頁面2的按鈕的時候,就會呼叫采用incrementScoreDelegate的Class,因此Class必須實作協(xié)定內(nèi)的方法。

被委托者 UIViewController
1.遵守協(xié)議:採用協(xié)定的方式是在 @interface 區(qū)段的地方加上 <協(xié)定名稱> 的程式碼,由于此協(xié)定是寫在其他的 class 中,所以在採用協(xié)定之前要先引用它,以下是頁面1的 UIViewController class.h 檔。

     //引用持有incrementScoreDelegate協(xié)定的class 
     #import "SecndViewController.h"
     //採用協(xié)定 
     @interface ViewController : UIViewController <incrementScoreDelegate>

2.設(shè)定為被委托者:在 .m 檔中實作協(xié)定內(nèi)的 incrementScore: 方法函式。

     - (void) incrementScore:(int)score from:(SecndViewController *)page {
         iTotalScore = iTotalScore + score;
         pScoreBoardLable.text = [NSString stringWithFormat:@"Score: %d", iTotalScore];
     }

3.覆寫協(xié)議方法: 如果忽略此步驟,頁面2里的 delegate 參數(shù)在呼叫 goBack 方法時,并不會知道是哪個 class實作了它的方法,因此參數(shù)也無法由頁面2SecndViewController傳遞至頁面1UIViewController。

     - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        //將 pNextPage 設(shè)定成Storyboard Segue的目標(biāo)UIViewController
            id pNextPage = segue.destinationViewController;
        //將值透過Storyboard Segue帶給頁面2 `pNextPage` 的string變數(shù)  
            [pNextPage setValue:[NSString stringWithFormat: @"%d", 1+rand()%10 ] forKey: @"strAttackPower"];
        //將delegate設(shè)成自己(指定自己為代理)  
            [pNextPage setValue:self forKey:@"delegate"];
       }

協(xié)議傳值的五步,最重要的是思考清楚,誰作為委托者,誰遵守協(xié)議,然后用這五個步驟來進(jìn)行實作。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容