代理是IOS开发中用到的一种设计模式。今天做了一个代理的小练习:
以下项目实现了两个页面之间的相互切换,并且在切换页面的时候完成了从一个页面往另一个页面的传值。从主页面往其他页面传值是容易的,但是反过来从其他页面往主页面传值就难了,要用到delegate设计模式。
新建一个ios的项目,然后再新建一个ViewController,起名为TwoViewController,这样,加上新建项目时默认生成的那个ViewController,总共有两个ViewController,其中新建项目默认生成的那个是主ViewController。
为了使用代理模式,我们要先定义一个协议,这个协议如下:
1 #import <Foundation/Foundation.h> 2 #import <UIKit/UIKit.h> 3 //定义一个协议,协议中定义一个传值的方法 4 //定义一个协议,协议中定义一个传值的方法 5 //定义一个协议,协议中定义一个传值的方法 6 @protocol Mydelegate <NSObject> 7 8 @required 9 -(void)changeValue:(NSString *)stringnow; 10 11 @end
协议中定义了一个传值的函数,用来把第二个ViewController中的值传给第一个ViewController,如果不是用代理,我们只能从第一个ViewController向第二个ViewController传值,而不能反过来,从第二个ViewController给第一个ViewController传值(具体原因没理解,以后理解了再补上)
完成协议后让第一个ViewController遵守这个协议,也就是在第一个ViewController的.h文件中声明第一个ViewController遵守这个协议<Mydelegate>:
1 #import <UIKit/UIKit.h> 2 3 //第一个页面应用Mydelegate协议 4 //第一个页面应用Mydelegate协议 5 //第一个页面应用Mydelegate协议 6 #import "Mydelegate.h" 7 @interface ViewController : UIViewController <Mydelegate> 8 9 10 @end
接下来在第一个ViewController的.m文件中实现changeValue这个传值方法:
1 #import "ViewController.h" 2 #import "TwoViewController.h" 3 @interface ViewController (){ 4 UITextField *textFieldnow; 5 6 } 7 8 @end 9 10 11 12 @implementation ViewController 13 14 //第一个页面引用Mydelegate协议,故要在.m文件中实现Mydelegate中定义的必须要实现的方法 15 //第一个页面引用Mydelegate协议,故要在.m文件中实现Mydelegate中定义的必须要实现的方法 16 //第一个页面引用Mydelegate协议,故要在.m文件中实现Mydelegate中定义的必须要实现的方法 17 -(void)changeValue:(NSString *)stringnow{ 18 textFieldnow.text=stringnow; 19 } 20 21 22 23 - (void)viewDidLoad { 24 [super viewDidLoad]; 25 // 初始化textFieldnow 26 textFieldnow = [[UITextField alloc]initWithFrame:CGRectMake(50 , 200, 200, 50)]; 27 28 // 设置textFieldnow的背景颜色 29 textFieldnow.backgroundColor = [UIColor colorWithRed:0.139 green:0.760 blue:1.000 alpha:1.000]; 30 31 // 为textFieldnow添加输入完成后让键盘消失的事件 32 [textFieldnow addTarget:self action:@selector(losefirstresponsder:) forControlEvents:UIControlEventEditingDidEndOnExit]; 33 34 // 把textFieldnow添加到view中 35 [self.view addSubview:textFieldnow]; 36 37 38 39 } 40 41 42 //本函数的功能是Textfield在输入完后按return让虚拟键盘消失 43 -(void)losefirstresponsder:(id)sender{ 44 [self resignFirstResponder]; 45 } 46 47 48 - (IBAction)TurnToNext:(id)sender { 49 TwoViewController *twoView = [[TwoViewController alloc]init]; 50 51 // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己 52 // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己 53 // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己 54 twoView.delegate = self; 55 56 57 // 把第一个界面的textFieldnow的值传给第二个界面中的namestring 58 twoView.namestring = textFieldnow.text; 59 60 61 // 跳转到第二个界面 62 [self presentViewController:twoView animated:YES completion:nil]; 63 64 } 65 66 - (void)didReceiveMemoryWarning { 67 [super didReceiveMemoryWarning]; 68 // Dispose of any resources that can be recreated. 69 } 70 71 @end
第二个ViewController的.h文件如下:
1 #import <UIKit/UIKit.h> 2 #import "Mydelegate.h" 3 4 @interface TwoViewController : UIViewController 5 6 @property(nonatomic,retain )NSString *namestring; 7 //定义一个变量delegate 8 //定义一个变量delegate 9 //定义一个变量delegate 10 @property(nonatomic,weak) id <Mydelegate> delegate; 11 12 @end
第二个ViewController的.m文件如下:
1 #import "TwoViewController.h" 2 3 @interface TwoViewController (){ 4 UILabel *label; 5 UITextField *textFieldnow1; 6 7 } 8 9 @end 10 11 @implementation TwoViewController 12 @synthesize namestring; 13 @synthesize delegate; 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 // Do any additional setup after loading the view from its nib. 17 label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 50)]; 18 [self.view addSubview:label]; 19 label.text = namestring; 20 textFieldnow1 = [[UITextField alloc]initWithFrame:CGRectMake(50 , 200, 200, 50)]; 21 22 textFieldnow1.backgroundColor = [UIColor colorWithRed:0.139 green:0.760 blue:1.000 alpha:1.000]; 23 [textFieldnow1 addTarget:self action:@selector(losefirstresponsder:) forControlEvents:UIControlEventEditingDidEndOnExit]; 24 [self.view addSubview:textFieldnow1]; 25 26 27 } 28 - (IBAction)BackToHome:(id)sender { 29 [self dismissViewControllerAnimated:YES completion:nil]; 30 [delegate changeValue:textFieldnow1.text]; 31 } 32 33 -(void)losefirstresponsder:(id)sender{ 34 [self resignFirstResponder]; 35 } 36 37 - (void)didReceiveMemoryWarning { 38 [super didReceiveMemoryWarning]; 39 // Dispose of any resources that can be recreated. 40 } 41 @end
要实现通过代理让第二个页面传递一个值给第一个页面,最关键的一点就是在第一个页面中要有一个指针指向self,也就是twoView.delegate = self;这条语句:
1 // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己 2 // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己 3 // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己 4 twoView.delegate = self;
而协议的作用就是提供了一个函数,起到了桥梁的作用。
时间: 2024-10-07 06:54:58