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;

     

运行效果图:

相关文章
相关标签/搜索