實現功能描述(簡單說明):在圖1中結算頁面點擊相關控件(如圖1中橙色方框標註的位置),推出圖2地址選擇頁面或者圖3所示的發票臺頭填寫頁面。函數
圖1 結算編碼
圖2 地址選擇atom
圖3 輸入發票臺頭
spa
說明:因爲這個Demo中的圖1點擊時,推出的頁面不少(這裏的圖片都只是顯示了一部分),而且不定,我這裏採用的方案是:.net
1. 定義一個改變UI的protocol:orm
@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;
運行效果圖: