代理是IOS开发中用到的一种设计模式。今天做了一个代理的小练习:
以下项目实现了两个页面之间的相互切换,并且在切换页面的时候完成了从一个页面往另一个页面的传值。从主页面往其他页面传值是容易的,但是反过来从其他页面往主页面传值就难了,要用到delegate设计模式。
新建一个ios的项目,然后再新建一个ViewController,起名为TwoViewController,这样,加上新建项目时默认生成的那个ViewController,总共有两个ViewController,其中新建项目默认生成的那个是主ViewController。
为了使用代理模式,我们要先定义一个协议,这个协议如下:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
//定义一个协议,协议中定义一个传值的方法
//定义一个协议,协议中定义一个传值的方法
//定义一个协议,协议中定义一个传值的方法
@protocol Mydelegate <NSObject> @required
-(void)changeValue:(NSString *)stringnow; @end
协议中定义了一个传值的函数,用来把第二个ViewController中的值传给第一个ViewController,如果不是用代理,我们只能从第一个ViewController向第二个ViewController传值,而不能反过来,从第二个ViewController给第一个ViewController传值(具体原因没理解,以后理解了再补上)
完成协议后让第一个ViewController遵守这个协议,也就是在第一个ViewController的.h文件中声明第一个ViewController遵守这个协议<Mydelegate>:
#import <UIKit/UIKit.h> //第一个页面应用Mydelegate协议
//第一个页面应用Mydelegate协议
//第一个页面应用Mydelegate协议
#import "Mydelegate.h"
@interface ViewController : UIViewController <Mydelegate> @end
接下来在第一个ViewController的.m文件中实现changeValue这个传值方法:
#import "ViewController.h"
#import "TwoViewController.h"
@interface ViewController (){
UITextField *textFieldnow; } @end @implementation ViewController //第一个页面引用Mydelegate协议,故要在.m文件中实现Mydelegate中定义的必须要实现的方法
//第一个页面引用Mydelegate协议,故要在.m文件中实现Mydelegate中定义的必须要实现的方法
//第一个页面引用Mydelegate协议,故要在.m文件中实现Mydelegate中定义的必须要实现的方法
-(void)changeValue:(NSString *)stringnow{
textFieldnow.text=stringnow;
} - (void)viewDidLoad {
[super viewDidLoad];
// 初始化textFieldnow
textFieldnow = [[UITextField alloc]initWithFrame:CGRectMake( , , , )]; // 设置textFieldnow的背景颜色
textFieldnow.backgroundColor = [UIColor colorWithRed:0.139 green:0.760 blue:1.000 alpha:1.000]; // 为textFieldnow添加输入完成后让键盘消失的事件
[textFieldnow addTarget:self action:@selector(losefirstresponsder:) forControlEvents:UIControlEventEditingDidEndOnExit]; // 把textFieldnow添加到view中
[self.view addSubview:textFieldnow]; } //本函数的功能是Textfield在输入完后按return让虚拟键盘消失
-(void)losefirstresponsder:(id)sender{
[self resignFirstResponder];
} - (IBAction)TurnToNext:(id)sender {
TwoViewController *twoView = [[TwoViewController alloc]init]; // 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己
// 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己
// 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己
twoView.delegate = self; // 把第一个界面的textFieldnow的值传给第二个界面中的namestring
twoView.namestring = textFieldnow.text; // 跳转到第二个界面
[self presentViewController:twoView animated:YES completion:nil]; } - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end
补充:
让键盘消失还有如下方法,思想是当鼠标点击文本框外的地方时,文本框就释放第一响应者的身份,代码如下:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ [textFieldinputUrl resignFirstResponder];
}
第二个ViewController的.h文件如下:
#import <UIKit/UIKit.h>
#import "Mydelegate.h" @interface TwoViewController : UIViewController @property(nonatomic,retain )NSString *namestring;
//定义一个变量delegate
//定义一个变量delegate
//定义一个变量delegate
@property(nonatomic,weak) id <Mydelegate> delegate; @end
第二个ViewController的.m文件如下:
#import "TwoViewController.h" @interface TwoViewController (){
UILabel *label;
UITextField *textFieldnow1; } @end @implementation TwoViewController
@synthesize namestring;
@synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
label = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];
[self.view addSubview:label];
label.text = namestring;
textFieldnow1 = [[UITextField alloc]initWithFrame:CGRectMake( , , , )]; textFieldnow1.backgroundColor = [UIColor colorWithRed:0.139 green:0.760 blue:1.000 alpha:1.000];
[textFieldnow1 addTarget:self action:@selector(losefirstresponsder:) forControlEvents:UIControlEventEditingDidEndOnExit];
[self.view addSubview:textFieldnow1]; }
- (IBAction)BackToHome:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
[delegate changeValue:textFieldnow1.text];
} -(void)losefirstresponsder:(id)sender{
[self resignFirstResponder];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
要实现通过代理让第二个页面传递一个值给第一个页面,最关键的一点就是在第一个页面中要有一个指针指向self,也就是twoView.delegate = self;这条语句:
// 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己
// 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己
// 委托机制最关键的部分,在跳转到第二个界面之前把第二个界面的委托对象指向自己
twoView.delegate = self;
而协议的作用就是提供了一个函数,起到了桥梁的作用。