- 监听事件也可以通过代理方法进行监听
- 在使用的时候可以使用对象的点语法看看有没delegate属性
- 代理也可以用来解耦,当两个类相互引用时可以用代理解耦
- id<协议>delegate,让任何遵守协议的代理都可以实现监听,实现协议方法
/**
* 代理设计模式的作用:
* 1.A对象监听B对象的一些行为,A成为B的代理
* 2.B对象想告诉A对象一些事情,A成为B的代理
*
* 代理设计模式的总结:
* 如果你想监听别人的一些行为,那么你就要成为别人的代理
* 如果你想告诉别人一些事情,那么就让别人成为你的代理
*
* 代理设计模式的开发步骤
* 1.拟一份协议(协议名字的格式:控件名 + Delegate),
1>在协议里面声明一些代理方法(一般代理方法都是@optional
2>代理方法名称:以控件名开头后面接行为名称
3>代理方法参数:把控件本身传过去,参数也可以用作数据传递
* 2.声明一个代理属性:@property (nonatomic, weak) id<代理协议> delegate;
* 3.在内部发生某些行为时,调用代理对应的代理方法,通知代理内部发生什么事
* 4.设置代理:xxx.delegate = yyy;
* 5.yyy对象遵守协议,实现代理方法
*/
- 举例:
- 在tableView的tableFooterView自定义类实现点击加载更多按钮
- 点击后通知控制器,获取网络数据,刷新cell
#import <UIKit/UIKit.h>
@class WQLoadMoreFooter;
/**
代理协议
*/
// 拟一份协议:前缀+控件名+Delegate
@protocol WQLoadMoreFooterDelegate <NSObject>
// 实现代理方法
@optional
- (void)loadMoreFooterDidClickLoadMoreButton:(WQLoadMoreFooter *)footer;
@end
/**
作为谁的代理,声明delegate属性,发出通知
*/
@interface WQLoadMoreFooter : UIView
+ (instancetype)footer;
// 在自定义控件中,声明一个代理属性
// 任何类型只要遵守协议,都可以做代理,可以减少耦合性
@property (nonatomic, weak) id<WQLoadMoreFooterDelegate> delegate;
@end
#import "WQLoadMoreFooter.h"
#import "WQDealsViewController.h"
@interface WQLoadMoreFooter()
@property (weak, nonatomic) IBOutlet UIButton *loadMoreButton;
@property (weak, nonatomic) IBOutlet UIView *loadingMoreView;
@end
@implementation WQLoadMoreFooter
+ (instancetype)footer
{
return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];
}
/**
* 点击了加载更多
*/
- (IBAction)loadMore {
self.loadMoreButton.hidden = YES;
self.loadingMoreView.hidden = NO;
// 告诉代理按钮点击了,也可以传输数据(作为函数参数)
if ([self.delegate respondsToSelector:@selector(loadMoreFooterDidClickLoadMoreButton:)]) {
[self.delegate loadMoreFooterDidClickLoadMoreButton:self];
}
}
@end
/**
控制器做的事情
*/
// 遵守协议
@interface WQDealsViewController () <WQLoadMoreFooterDelegate>
#pragma mark - <WQLoadMoreFooterDelegate>
- (void)loadMoreFooterDidClickLoadMoreButton:(WQLoadMoreFooter *)footer
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 获取网络数据加载数据,添加到tablview的数组数组中
// 刷新表格
[self.tableView reloadData];
// 做一些事情
}