2015年9月28日 星期一

iOS筆記:Implement Protocols

The way we passing the information back to a previous ViewController, we couldn’t create a property of ViewController B if i was coming from C. because we don’t wanna create a new instance of ViewController B, we anna use the instance ViewController B. so we want pass information back to that ViewController that’s still being held in memory.

First, need to reference that current ViewController. And the way to reference it, is using delegate property.

流程圖:
enter image description here

為一個類別定義一個協定,必須使用 @protocol 區段來定義它,它至少必須包含協定的名稱與協定的內容方法,協定名稱的命名方式,通常是以該類別的名稱加上 Delegate 來表示。

這個練習是要讓DetailViewController的資料可以傳到FirstPage (ViewController).

資料傳遞方向和 Segue 相反,所以在資料的傳送端建立 Protocol 而資料的接受端就是 delegate 的對像,就要實作傳送端的 Protocol 提到的 method 才可以收到資料。

enter image description here

# DetailViewController.h
#import <UIKit/UIKit.h>

@protocol DetailViewControllerDelegate <NSObject>
- (void)didUpdateText: (NSString *)text;
@end

@interface DetailViewController : UIViewController

@property (weak, nonatomic) id <DetailViewControllerDelegate> delegate;

....

@end

在定義協定之後,還必須定義它何時生效,就像合約都有生效日期一般,協定的生效位置則是定義在程式碼裡,並且生效的位置不應該在類別的建構式中,如果協定內同時定義許多方法,則可以在不同的位置,分別使它們生效。同樣我們在 Furnace 類別中宣告一個採納此協定的變數,採納協定的方法是使用角括號 <協定名稱> 來表示

@property (weak, nonatomic) id <DetailViewControllerDelegate> delegate;
//CMAddSpaceObjectViewControllerDelegate 是我們自訂的Delegate.

Why use weak??? because we wanna retain cycles. and be noted that if we creat delegate properties, we’re gonna declare them as weak. So that we’ll be able to propertly deallocate objects when we need to.

// DetailViewController.m

#import "DetailViewController.h"
@implementation DetailViewController

...

- (IBAction)updateButton:(id)sender {
    self.Label.text = self.textfield.text;
    [self.delegate didUpdateText:self.Label.text];
}
@end
//  ViewController.m
#import "ViewController.h"
#import "DetailViewController.h"

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([sender isKindOfClass:[UIButton class]]) {
        if ([segue.destinationViewController isKindOfClass:[DetailViewController class]])
        {
            DetailViewController *detailVC = segue.destinationViewController;
            detailVC.infomationFromTextField = self.textField.text;
            **detailVC.delegate = self;**
        }
    }
}

#pragma Delegate
- (void)didUpdateText:(NSString *)text
{
    self.textField.text = text;
}
@end

protocol本身也可以像一般類別的繼承.

@protocol A
-(void) methodA;
@end

@protocol B <A>
-(void) methodB;
@end

如果你要實作protocol B,則methodA跟methodB都需要實作。

The way to make keyboard go away when we press return key.

Use UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self.textField resignFirstResponder];
    return YES;
}

參考網址:
1. http://furnacedigital.blogspot.tw/2012/01/protocol.html

沒有留言:

張貼留言