iOS技巧篇之UIViewController与UIView的双向交互
1.场景描述
在iOS开发过程中,一般都是UIViewController来控制UIView的行为,一般很少方向交互,即UIView的特性变化后调用UIViewController的相应的方法,在遇到这种情况,大多数都采用了在UIView的子类中放一个UIViewController的指针,当UIView需要调用UIViewController的方法的时候,就可以通过这个指针来实现了。
2.解决方案
这种方法是有效的(C/C++常用哦),但总是觉得不够优雅,有没有其他办法来实现呢,答案是肯定的,估计很多人都已经想到了,那就是委托(Delegate),其实iOS中很多界面元素都使用这种方式与UIViewController交互,这种方式给人的感觉更“Apple化"一些!
3.主要知识点
委托模式能够起到两方面的作用:
第一:委托协助对象主体完成某项操作,将需要定制化的操作通过委托对象来自定义实现,达到和子类化对象主体同样的作用。
第二:事件监听,委托对象监听对象主体的某些重要事件,对事件做出具体响应或广播事件交给需要作出响应的对象。
个人理解采用委托模式的好处在于:
A、避免子类化带来的过多的子类以及子类与父类的耦合
B、通过委托传递消息机制实现分层解耦
4.请看代码
4.1实现委托前的代码
4.1.1 MainViewController.h
// // MainViewController.h // WellLogGraph // // Created by wanglei on 13-8-23. // Copyright (c) 2013年 wanglei. All rights reserved. // #import <UIKit/UIKit.h> @interface MainViewController : UIViewController @end
4.1.2 MainViewController.m
// // MainViewController.m // WellLogGraph // // Created by wanglei on 13-8-23. // Copyright (c) 2013年 wanglei. All rights reserved. // #import "MainViewController.h" #import "WellLogMapView.h" @interface MainViewController () @end @implementation MainViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } -(void)viewWillAppear:(BOOL)animated { WellLogMapView* v = (WellLogMapView*)self.view; [v setNeedsDisplay]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
4.1.3 WellLogMapView.h
// // WellLogMapView.h // WellLogGraph // // Created by wanglei on 13-8-24. // Copyright (c) 2013年 wanglei. All rights reserved. // #import <UIKit/UIKit.h> @interface WellLogMapView : UIView { } @end
4.1.4 WellLogMapView.m
// // WellLogMapView.m // WellLogGraph // // Created by wanglei on 13-8-24. // Copyright (c) 2013年 wanglei. All rights reserved. // #import "WellLogMapView.h" @implementation WellLogMapView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //UITouch *touch = [touches anyObject]; // 希望在这里告诉MainViewController做一些活动,也就是如何调用MainViewController的方法 } @end
4.2实现委托后的代码
4.2.1 MainViewController.h
// // MainViewController.h // WellLogGraph // // Created by wanglei on 13-8-23. // Copyright (c) 2013年 wanglei. All rights reserved. // #import <UIKit/UIKit.h> @protocol WellLogMapViewDelegate -(void)onSelectionChanged:(id)selection; @end @interface MainViewController : UIViewController<WellLogMapViewDelegate> -(void)onSelectionChanged:(id)selection; @end
4.2.2 MainViewController.m
// // MainViewController.m // WellLogGraph // // Created by wanglei on 13-8-23. // Copyright (c) 2013年 wanglei. All rights reserved. // #import "MainViewController.h" #import "WellLogMapView.h" @interface MainViewController () @end @implementation MainViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.navigationItem.rightBarButtonItem.title = @"添加分栏"; [self.navigationItem.rightBarButtonItem initWithBarButtonSystemItem:UIBarButtonSystemItemUndo target:self action:@selector(myAction)]; WellLogMapView* view = (WellLogMapView*)self.view; [view setDelegate:self]; } -(void)viewWillAppear:(BOOL)animated { WellLogMapView* v = (WellLogMapView*)self.view; [v setNeedsDisplay]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)onSelectionChanged:(id)selection { //do something } @end
4.2.3 WellLogMapView.h
// // WellLogMapView.h // WellLogGraph // // Created by wanglei on 13-8-24. // Copyright (c) 2013年 wanglei. All rights reserved. // #import <UIKit/UIKit.h> #import "MainViewController.h" @interface WellLogMapView : UIView { id<WellLogMapViewDelegate> delegate; } @property (nonatomic, retain) id delegate; @end
4.2.4 WellLogMapView.m
// // WellLogMapView.m // WellLogGraph // // Created by wanglei on 13-8-24. // Copyright (c) 2013年 wanglei. All rights reserved. // #import "WellLogMapView.h" @implementation WellLogMapView @synthesize delegate; - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //UITouch *touch = [touches anyObject]; [delegate onSelectionChanged:nil]; } @end
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。