KVO 實現兩個頁面之間的通訊

實現功能描述(簡單說明):在圖1中結算頁面點擊相關控件(如圖1中橙色方框標註的位置),推出圖2地址選擇頁面或者圖3所示的發票臺頭填寫頁面。函數

                          圖1 結算編碼

                          圖2 地址選擇atom

                          圖3 輸入發票臺頭 
spa

說明:因爲這個Demo中的圖1點擊時,推出的頁面不少(這裏的圖片都只是顯示了一部分),而且不定,我這裏採用的方案是:.net

1. 定義一個改變UI的protocolorm

@protocol  LYGAddressProtocal <NSObject>server


-(void)backToPreviousVC;對象

-(void)changeContentWithContentNum:(int)contentNum;繼承

-(void)refreshUIWithStr:(NSString *)str andContentNum:(int)contentNum;圖片


2. 定義兩個繼承自 UIViewController

結算頁面類:

@interface  LYGPayViewController : UIViewController

被推出頁面的類:

@interface  LYGAddressViewController : UIViewController<LYGAddressProtocal>

//聲明 監聽對象

@property (nonatomic,copy) NSString *userInfo;

@property (nonatomic,copy) NSString *transforWayStr;


@property (nonatomic,weak)LYGFaPiaoView *faPiaoVC;


3. 建立各類相對應的 xib;

emptyAddress.xib

selectAddress.xib

transformTime.xib

......

4.  自定義相應的各類繼承自 UIView的類,將其與步驟3中建立的xib關聯起來

@interface  LYGEmptyAddressView : UIView

@interface  LYGSelectAddVIew : UIView

@interface  LYGTransformTimeView : UIView

......

5. 在步驟2中建立的類中,示例化各類類(示例)

LYGEmptyAddressView *emptyAddressView = [[NSBundle mainBundle]loadNibNamed:@"emptyAddress" owner:nil options:nil][0];

emptyAddressView.delegateVC = self;

emptyAddressView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

[self.view addSubview:emptyAddressView];


-(void)refreshUIWithStr:(NSString *)str andContentNum:(int)contentNum

{    

    switch (contentNum) {

        case 01:

            self.userInfo = str;//使用點語法

            break;

        case 10:

            [self setValue:str forKey:@"transforWayStr"];// 聽從KVC編碼風格設置key-value

            break;

        default:

            break;

    }

}


在自定義的繼承自view的類中調用上面的刷新頁面函數

6. 在 結算類 .m 文件中註冊監聽者,而且實現監聽回調函數

static void* userInfo = (void *)&userInfo;

static void* transforWayStr = (void *)&transforWayStr;


LYGAddressViewController *addVC = [[LYGAddressViewController alloc]initWithNibName:@"LYGAddressViewController" bundle:nil];

  

    [addVC addObserver:self forKeyPath:@"userInfo" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:userInfo];

    

    [addVC addObserver:self forKeyPath:@"transforWayStr" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:transforWayStr];

.......

#pragma mark 監聽回調函數

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

    NSLog(@"-----observer-----");

    if (context == userInfo) {

        NSString *oldStr = [change objectForKey:@"old"];

        NSString *newStr = [change objectForKey:@"new"];

        self.myAddInfoLabel.text = newStr;

    }

    else if(context == transforWayStr)

    {

        NSString *oldStr = [change objectForKey:@"old"];

        NSString *newStr = [change objectForKey:@"new"];

        self.myTransforGoodsWayLabel.text = newStr;

    }

    else

    {

        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

    }

}


注:對於監測對象中對象的屬性的狀況,須使用方法(都必須遵照KVC編碼格式)

setValue:<#(id)#> forKeyPath:<#(NSString *)#>(正確)

不能在使用:

setValue:<#(id)#> forKey:<#(NSString *)#>(錯誤)

示例:

[self.delegateVC setValue:self.myInvoiceTextFeild.text forKeyPath:@"invoiceVC.myInvoiceTextFeild"];

[self.delegateVC setValue:self.myInvoiceTextFeild.text forKeyPath:@"invoiceVC.myInvoiceTextFeild.Text"];


對於第一種須要回調函數種須要作特別的判斷,第二種則不須要新值一直是NSString類型的 。


第一種註冊監聽:

[addVC addObserver:self forKeyPath:@"invoiceVC.myInvoiceTextFeild" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:invoiceStr];

第一種回調函數

       NSString *oldStr = [change objectForKey:@"old"];

        id newObj = [change objectForKey:@"new"];        

        

        if([newObj isKindOfClass:[NSString class]])

        {

            NSString *s = newObj;

            self.myInvoiceLabel.text = s;

        }

        else if ([newObj isKindOfClass:[UITextField class]])

        {

            UITextField *ff = newObj;

            self.myInvoiceLabel.text = ff.text;

        }


第二種註冊監聽:

[addVC addObserver:self forKeyPath:@"invoiceVC.myInvoiceTextFeild.Text" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:invoiceStr];

第二種回調函數

       NSString *oldStr = [change objectForKey:@"old"];

       NSString *newStr = [change objectForKey:@"new"];        

       self.myInvoiceLabel.text = newStr;

     

運行效果圖:

相關文章
相關標籤/搜索