分享

iOS 之美:透过Delegate ,看UIView与UIViewController之间的关系

 最初九月雪 2014-11-22

 在Cocoa Touch 框架中, 所有的控件和视图都继承于UIView。 UIView 负责UI 的展示。UIView所接收到的触摸事件,都以Delegate的方式,交给UIViewController来处理。

需要注意的是,每个UIView都有自己的UIViewController。 比如,我们常用到的UITableView,它所对应的Controller就是UITableViewController。

接下来,我们看看UIView 的架构是怎样的。

简单回顾下@interface 和@protocol 这两个关键字。

@interface 用来定义一个类;

@protocol 用来定义一个协议; 也可以理解为,@protocol就是定义了一个protocol。 至于为什么叫 protocol, 不妨认为这是Objective-C 独有的东西吧。


第一步: 在 view.h 文件中声明一个delegate

 (1)  定义一个UIView类

首先,定义一个UIView 的子类:

@interface  MyUIView: UIView

{

@property id<MyUIViewDelegate> delegate; 

}

@end

其他都容易理解,难点在于 delegate的定义和实现上。

先有个感性认识吧:出现<> 的地方,表示这是一个protocol类型。 Protocol前的id 是一个通用类型。暂且不管它。

id<MyUIViewDelegate> delegate;   这行代码表示, 我们用 <MyUIViewDelegate> 定义了一个protocol, 并且,把这个新定义的protocol 命名为delegate。

或许你感到纳闷,为什么非得命名为delegate 呢?  其实啊,这只是声明的一个protocol, 它与我们挂在嘴边的delegate 术语,没什么关系。

先提示下, delegate 是一种设计模式。 在Objective-C中, 它是通过protocol 的定义来实现的。

不过,按照Cocoa 的习惯, 在UIView 中所声明的这个protocol,一般都是命名为delegate,或以delegate 结尾。


   (2) 声明一个protocol

通过@protocol,可以 定义一组函数。从本质上来说,这些函数就是回调函数。

@protocol  MyUIViewDelegate

- method_a;

- method_b;

@end

MyUIViewDelegate 这种以 delegate结尾的命名方法, 预示着这个protocol将要完成delegate 所肩负的职责。

 

第二步: 在 viewController 文件中,实现这个delegate


     设计自己的UIViewController一个简单的做法是,让这个Controller来实现上面定义的MyUIViewDelegate。在Cocoa框架中,很多控件和它的Controller都是采用的这种方式。

@interface MyUIViewController : UIViewController <MyUIViewDelegate>

{
      //方法声明; (method declaration)

//属性声明(Property  declaration)

}

@end

 

 建立view、 delegate、 view controller 三者之间的关系

 我们已经定义了 MyUIView、<MyUIViewDelegate> 和 MyUIViewController。

到这里其实还看不出这三者是怎么关联的。接下来就要看看,MyUIView和MyUIViewController的具体实现了。
首先是MyUIView的实现代码,假设在MyUIView视图中发生某个事件后,会调用doSometing方法。


- (void)doSomething
{
if( delegate != nil )  
{
[delegate method_a];  
}
}

if( delegate != nil )   这行语句的意思是,如果delegate对象不为空,则调用相应的方法,但是这个对象的方法 (method_a)在哪里实现呢?  按照Delegate 的设计模式, MyUIViewDelegate所定义的方法,应由MyUIViewController 来实现。 代码如下:


在 viewcontroller. m 文件中, 实现以下代码:

- (id)init
{
MyUIView *myView = [[MyUIView alloc] init];  //对MyUIView进行初始化
myView.delegate = self;   // 将MyUIViewController自己的实例作为委托对象
self.view = myView; 
}

解释:  这里的self 所指的就是 viewcontroller。  myView.delegate = self; 的意思: 将view 的委托设为 view controller。 通俗地讲: 视图所委托的活儿,由视图控制器完成。 


- (void)method_a
{
……
}


  小结

这么一来,整个代码的思路,就很清晰了。
1. 重写 MyUIViewController初始化函数;
2. 初始化MyUIView,并将MyUIView的委托对象设为 MyUIViewController;
3. 当MyUIView有事件触发时,调用MyUIViewDelegate所定义的方法。


更多 iOS技术交流,尽在 QQ群: iOS之美   238303969

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多