一、属性传值
在SecondViewController.h里
#import <UIKit/UIKit.h> @interface SecondViewController : UIViewController // 第一步:声明属性,用来存放上一页传过来的数据 @property (nonatomic, copy) NSString *contents; @end
在RootViewController.m里
- (void)loginAction { SecondViewController *sVC = [[SecondViewController alloc] init]; // 第二步进行赋值 sVC.contents = self.rootView.userTextField.text; [self.navigationController pushViewController:sVC animated:YES]; }
在SecondViewController.m里
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.title = @"欢迎"; self.view.backgroundColor = [UIColor grayColor]; [self initLayout]; // 第三步,显示内容 self.nameLabel.text = self.contents; }
二、协议传值
1、协议六步
- 第一步:声明协议
- 第二步:声明代理人
- 第三步:执行协议方法
- 第四步:签订协议
- 第五步:指定代理人
- 第六步:实现协议方法
2、代码
第一步:在SecondViewController.h里声明协议
// 1.定义协议 @protocol SecondViewControllerDelegate <NSObject> // 声明协议方法 - (void)changeValue:(NSString *)name; @end
第二步:在SecondViewController.h里声明代理人
@interface SecondViewController : UIViewController // 声明代理人,语义设置使用assign,防止循环引用 @property (nonatomic, assign) id<SecondViewControllerDelegate>secondDelegate; @property (nonatomic, strong) NSString *contents; @end
第三步:在SecondViewController.m使用代理调用代理的传值方法
// 实现方法使用代理从后往前传值 - (void)myBtnAction:(UIButton *)sender { // 1.把输入的内容传到第一页 // 第三步:使用代理调用代理的传值方法 // 判断代理是否实现了方法进行调用 if ([self.secondDelegate respondsToSelector:@selector(changeValue:)]) { [self.secondDelegate changeValue:self.myField.text]; } // 2.跳回到第一页 [self.navigationController popViewControllerAnimated:YES]; }
第四步:在RootViewController.m的延展里签订协议
// 第四步:签订协议 @interface RootViewController ()<SecondViewControllerDelegate> @property (nonatomic, strong) UILabel *myLabel; @property (nonatomic, strong) UIButton *myBtn; @end
第五步:在RootViewController.m指定当前对象为代理人
// 实现事件 - (void)rightAction { SecondViewController *sVC = [[SecondViewController alloc] init]; // 第五步:指定当前对象为代理人 sVC.secondDelegate = self; [self.navigationController pushViewController:sVC animated:YES]; }
第六步:在RootViewController.m实现协议方法
// 第六步:实现协议方法 - (void)changeValue:(NSString *)name { self.myLabel.text = name; }
三、Block传值
1、回顾block
- block是匿名函数,能够实现函数回调功能
- 用于页面之间通信,同时可以进行传值
void(^block)(void) = ^(void) { }; //其中: //void(^block)(void)是类型 //block是变量名 //^(void){};是block实现 // 没有使用局部变量的block存储在全局区 // 使用局部变量的block存储在栈区
2、block传值
- 使用场景类似协议传值,都是解决从后一个页面往前一个页面传值问题
3、block传值两种方式
- 方式一:使用block属性实现回调传值
- 方式二:在方法中定义block实现回调传值
在SecondViewController.h声明block
@interface SecondViewController : UIViewController // 第一步:定义block属性 @property (nonatomic, copy) void (^block)(NSString *); @end
在FirstViewController.m实现block
- (void)myBtnAction { SecondViewController *secondVC = [[SecondViewController alloc] init]; // 第二步:实现block secondVC.block = ^void (NSString *textString) { self.myLable.text = textString; }; [self.navigationController pushViewController:secondVC animated:YES]; }
在SecondViewController.m进行block传值
// 实现方法 进行block传值 - (void)myBtnAction { // block传值 self.block(self.myField.text); // 返回第一页 [self.navigationController popViewControllerAnimated:YES]; }
四、Block内存管理
1、在.h里声明block
#import <UIKit/UIKit.h> @interface SecondViewController : UIViewController // 注意在MRC下,使用copy,在ARC下,可以使用copy,也可以使用strong来修饰,在strong中碰到block会自动有copy到堆内存的功能,但是苹果官方还是推荐使用copy,strong的内部实现也是copy @property (nonatomic, copy) void (^block) (); @end
2、在.m里实现block
// 实现block /** * 在controller中定义block属性 实现block的时候,如果block里面需要使用当前控制器对象,不可以直接使用self,否则会引起循环引用 */ // 使用__weak 修饰防止循环引用 // __weak SecondViewController *secondVC = self; __weak typeof(self) secondVC = self; self.block = ^void () { NSLog(@"这事block的实现"); secondVC.view.backgroundColor = [UIColor redColor]; }; // 调用block self.block();
时间: 2024-10-29 19:10:33