博主最近在面iOS实习生,有一天面试官提出一个问题问我,如何使用delegate在两个控制器之间进行传值操作,因为是手写,没有调试工能,就这个控制器写协议,觉得不对,然后那个控制器也写协议,最后终于把自己弄混了,面试结束用Xcode,编译了一遍,虽然真的是很简单,但是也有一些不容易发现的小技巧,也在下面的图片中的注释列举出来了,有问题尽管提问
我虽然也搜到了部分的控制器之间使用delegate传值,但是都是代码,讲解也少,所以就发出个图片加代码加GIF的,以便理解。
本题为 SecondViewController -> ViewController
ViewController.h
1 // 2 // ViewController.h 3 // 两个控制器之间使用代理传值 4 // 5 // Created by ma c on 16/5/6. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @interface ViewController : UIViewController 12 13 14 @end
至于为什么要在ViewContorller中实现代理方法,个人理解为ViewContorller为主控制器,可以偷懒少些很多代码。。。
ViewController.m
1 // 2 // ViewController.m 3 // 两个控制器之间使用代理传值 4 // 5 // Created by ma c on 16/5/6. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "SecondViewController.h" 11 12 // 服从SecondViewController的协议,并且实现协议之中的方法 13 14 @interface ViewController ()<SecondViewControllerDelegate> 15 16 @end 17 18 @implementation ViewController 19 20 - (void)viewDidLoad { 21 [super viewDidLoad]; 22 23 self.view.backgroundColor = [UIColor grayColor]; 24 } 25 26 //写一个点击方法,不愿意去写btn。。。 27 28 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 29 30 SecondViewController *secondVC = [[SecondViewController alloc] init]; 31 32 /* 33 **************************** 34 35 现在要实现的是SecondViewController 给 ViewController 传值 36 37 所以需要在viewController里面给delegate属性赋值 38 39 关于顺序关系:一定要先给delegate属性赋值,然后在调用view属性 40 41 **************************** 42 */ 43 44 secondVC.delegate = self; 45 46 secondVC.view.backgroundColor = [UIColor redColor]; 47 48 //模态视图 用来加载secondVC的viewDidLoad 49 50 [self presentViewController:secondVC animated:YES completion:nil]; 51 } 52 53 - (void)SecondViewController:(SecondViewController *)viewController andSendTitle:(NSString *)title { 54 55 NSLog(@"%@ %@",viewController,title); 56 } 57 58 @end
SecondViewController.h
1 // 2 // SecondViewController.h 3 // 两个控制器之间使用代理传值 4 // 5 // Created by ma c on 16/5/6. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @class SecondViewController; 12 13 /** 14 * 声明一个协议,来实现控制器之间的代理传值(SecondViewController的协议) 15 */ 16 @protocol SecondViewControllerDelegate <NSObject> 17 18 /** 声明一个方法,进行控制器之间的传值 */ 19 - (void)SecondViewController:(SecondViewController *)viewController andSendTitle:(NSString *)title; 20 21 @end 22 23 @interface SecondViewController : UIViewController 24 25 /** 声明代理属性*/ 26 @property (nonatomic, weak)id <SecondViewControllerDelegate> delegate; 27 28 @end
SecondViewController.m
1 // 2 // SecondViewController.m 3 // 两个控制器之间使用代理传值 4 // 5 // Created by ma c on 16/5/6. 6 // Copyright © 2016年 彭盛凇. All rights reserved. 7 // 8 9 #import "SecondViewController.h" 10 11 @interface SecondViewController () 12 13 @end 14 15 @implementation SecondViewController 16 17 - (void)viewDidLoad { 18 [super viewDidLoad]; 19 // Do any additional setup after loading the view. 20 21 //判断delegate属性是否赋值成功,并且是否可以响应协议中的方法,如果能响应的话就调用协议中的方法 22 23 if ([self.delegate respondsToSelector:@selector(SecondViewController:andSendTitle:)]) { 24 [self.delegate SecondViewController:self andSendTitle:@"你好"]; 25 } 26 27 } 28 29 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 30 31 [self dismissViewControllerAnimated:YES completion:nil]; 32 33 } 34 35 @end
在文章的最后说一下本人对delegate的理解
B -> A
一般来说
- 在B.h中声明代理协议,并声明delegate变量,注:id类型,weak修饰,服从本代理
- 在B.m中判断delegate是否已经赋值成功,delegate是否可以响应协议中的方法,并调用协议中的方法,实现反向传值
- 在A.m中引入B的头文件,并服从协议,同时给B.delegate赋值,并实现协议方法。