天天看点

KVO 实现两个页面之间的通信

实现功能描述(简单说明):在图1中结算页面点击相关控件(如图1中橙色方框标注的位置),推出图2地址选择页面或者图3所示的发票台头填写页面。

KVO 实现两个页面之间的通信

                          图1 结算

KVO 实现两个页面之间的通信

                          图2 地址选择

KVO 实现两个页面之间的通信

                          图3 输入发票台头 

说明:由于这个Demo中的图1点击时,推出的页面很多(这里的图片都只是显示了一部分),并且不定,我这里采用的方案是:

1. 定义一个改变UI的protocol:

@protocol  LYGAddressProtocal <NSObject>

-(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;

运行效果图:

KVO 实现两个页面之间的通信

版权声明:本文为CSDN博主「weixin_34081595」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_34081595/article/details/91972222