一、首先介绍Protocol
1、协议protocol说明
protocol:定义公用的一套接口,但不提供具体的实现方法。
协议约定可选择实现的方法和必须实现的方法。
@required:必须实现的方法
@optional:可选是否实现的方法
2、协议protocol的使用
//创建协议文件protocolDelegate
//1.new file -->Objective-C File-->选择Protocol,创建Protocol文件
//protocol文件只有.h文件,只声明方法。
#import <Foundation/Foundation.h>
@protocol protocolDelegate <NSObject>
@required
//必须实现的方法
- (void)eat;
- (void)drink;
// 可选实现的方法
@optional
- (void)readBook;
- (void)writeCode;
@end
//创建student类和programmer类具体实现对应方法
//2.创建student类
//Student.h
#import <Foundation/Foundation.h>
#import "protocolDelegate.h"
@interface Student : NSObject <protocolDelegate>
@end
//Student.m
#import "Student.h"
@implementation Student
- (void)eat {
NSLog(@"%@",@"我是学生,我必须得吃饭,我吃米饭");
}
- (void)drink {
NSLog(@"%@",@"我是学生,我必须得喝水,我喝饮料");
}
- (void)readBook {
NSLog(@"%@",@"我是学生,我会读书");
}
@end
//3.创建Programma类
//Programma.h
#import <Foundation/Foundation.h>
#import "protocolDelegate.h"
@interface Programmer : NSObject <protocolDelegate>
@end
//Programma.m
#import "Programmer.h"
@implementation Programmer
- (void)eat {
NSLog(@"%@",@"我是工程师,我必须得吃饭,我吃火锅");
}
- (void)drink {
NSLog(@"%@",@"我是工程师,我必须得喝水,我喝啤酒");
}
- (void)writeCode {
NSLog(@"%@",@"我是工程师,我会写代码");
}
@end
//调用方法
//在viewcontroller里调用
#import "ViewController.h"
#import "Student.h"
#import "Programmer.h"
@interface ViewController ()
@property (nonatomic, strong) Student *student;
@property (nonatomic, strong) Programmer *programmer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self dinerTogether];
}
// 聚餐
- (void)dinerTogether {
[self eatTogether];
[self drinkTogether];
[self doMySelf];
}
- (void)eatTogether {
if ([self.student respondsToSelector:@selector(eat)]) {
[self.student eat];
}
if ([self.programmer respondsToSelector:@selector(eat)]) {
[self.programmer eat];
}
}
- (void)drinkTogether {
if ([self.student respondsToSelector:@selector(drink)]) {
[self.student drink];
}
if ([self.programmer respondsToSelector:@selector(drink)]) {
[self.programmer drink];
}
}
- (void)doMySelf {
if ([self.student respondsToSelector:@selector(readBook)]) {
[self.student readBook];
}
if ([self.programmer respondsToSelector:@selector(writeCode)]) {
[self.programmer writeCode];
}
}
#pragma mark - getter and setter
- (Student *)student {
if (!_student) {
_student = [[Student alloc] init];
}
return _student;
}
- (Programmer *)programmer {
if (!_programmer) {
_programmer = [[Programmer alloc] init];
}
return _programmer;
}
@end
注:一般多个类要实现共同的方法,又各自有自己要实现的方法时,可使用Protocol
一、delegate简介
代理设计模式,是iOS中一种消息传递的方式,由代理对象、委托者、协议组成。
- 协议:用来指定代理可以做什么,必须做什么。
- 代理:根据指定协议,完成委托方需要实现的方法。
- 委托:根据指定协议,指定代理必须完成和可以完成方法。
二、delegate的使用
1、传值
//下一控制器传值给上一控制器
//下一控制器NextViewController文件
//NextViewController.h文件
#import <UIKit/UIKit.h>
@protocol NextViewControllerDelegate <NSObject>
- (void)sendValue:(NSString *)string;
@end
@interface NextViewController : UIViewController
@property (nonatomic, weak) id<NextViewControllerDelegate> delegate;
@end
//NextViewController.m文件
#import "NextViewController.h"
@interface NextViewController ()
//创建一个TextField输入要传端值
@property (nonatomic, strong) UITextField *tf_sendValue;
//创建返回上一控制器的按钮
@property (nonatomic, strong) UIButton *btn_backVc;
@end
@implementation NextViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// 添加TextField
UITextField *tf_sendValue = [[UITextField alloc]init];
tf_sendValue.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
tf_sendValue.textAlignment = 1;
tf_sendValue.placeholder = @"请输入要传递的值";
self.tf_sendValue = tf_sendValue;
[self.view addSubview:tf_sendValue];
// 添加返回上一控制器的按钮
UIButton *btn_backVc = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 150, 35)];
[btn_backVc setTitle:@"返回上一控制器" forState:UIControlStateNormal];
[btn_backVc setBackgroundColor:[UIColor redColor]];
btn_backVc.center = self.view.center;
self.btn_backVc = btn_backVc;
[self.view addSubview:btn_backVc];
//添加点击事件
[self.btn_backVc addTarget:self action:@selector(clickBackBtn) forControlEvents:UIControlEventTouchUpInside];
}
- (void)clickBackBtn{
[self.navigationController popViewControllerAnimated:YES];
NSString *str = self.tf_sendValue.text;
if (str.length>0) {
if ([self.delegate respondsToSelector:@selector(sendValue:)]) {
[self.delegate sendValue:str];
}
}
}
@end
//上一控制器遵循协议,实现代理方法,获取传递的值
//ViewController.m文件
#import "ViewController.h"
#import "NextViewController.h"
@interface ViewController ()<NextViewControllerDelegate>
//创建一个Label显示下一界面传过来的值
@property (nonatomic, strong) UILabel *lb_showStr;
//创建push下一界面按钮
@property (nonatomic, strong) UIButton *btn_nextVc;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"第一个控制器";
self.view.backgroundColor = [UIColor whiteColor];
// 添加lb_showStr
UILabel *lb_showStr = [[UILabel alloc]init];
lb_showStr.frame = CGRectMake(0, 100, self.view.frame.size.width, 30);
lb_showStr.textAlignment = NSTextAlignmentCenter;
lb_showStr.text = @"显示下一界面的传值";
self.lb_showStr = lb_showStr;
[self.view addSubview:lb_showStr];
// 添加push下一控制器按钮
UIButton *btn_nextVc = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 150, 35)];
[btn_nextVc setTitle:@"push下一界面" forState:UIControlStateNormal];
[btn_nextVc setBackgroundColor:[UIColor redColor]];
btn_nextVc.center = self.view.center;
self.btn_nextVc = btn_nextVc;
[self.view addSubview:btn_nextVc];
//添加点击事件
[self.btn_nextVc addTarget:self action:@selector(clickPushBtn) forControlEvents:UIControlEventTouchUpInside];
}
- (void)clickPushBtn{
NextViewController *nextVc = [[NextViewController alloc]init];
[self.navigationController pushViewController:nextVc animated:YES];
nextVc.delegate = self;
}
- (void)sendValue:(NSString *)string{
self.lb_showStr.text = string;
}
@end
2、传递事件
//点击自定义view,传递view点击事件
//1.MyView.h
#import <UIKit/UIKit.h>
@protocol MyViewDelegate <NSObject>
- (void)myViewDelegateFunc;
@end
@interface MyView : UIView
//声明代理属性
@property (nonatomic, weak) id<MyViewDelegate> myViewDelegate;
@end
//2.MyView.m
#import "MyView.h"
@implementation MyView
//点击view,响应代理方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if ([_myViewDelegate respondsToSelector:@selector(myViewDelegateFunc)]) {
[_myViewDelegate myViewDelegateFunc];
}
}
@end
//实现代理方法
#import "ViewController.h"
#import "MyView.h"
@interface ViewController ()<MyViewDelegate>
@property (nonatomic, strong) MyView *myView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
MyView *myView = [[MyView alloc]init];
myView.myViewDelegate = self;
self.myView = myView;
myView.backgroundColor = [UIColor redColor];
myView.frame = CGRectMake(100, 100, 100, 100);
myView.center = self.view.center;
myView.userInteractionEnabled = YES;
[self.view addSubview:self.myView];
}
#pragma mark - myViewDelegate代理方法
- (void)myViewDelegateFunc{
NSLog(@"myViewDelegate的代理 点击view");
}
@end
注:代理实现了不同视图之间的数据交互,只有某一事件触发才会被调用。在使用代理时,代理者要遵循代理,设置代理,实现代理方法。只有设置了代理,才能调用代理方法。