iOSDay27之界面通信

1. 属性传值(前面的界面给后面传值)

 第一步: 在 SecondViewController.h 文件里定义一个存放传过来值的变量 contents

1 #import <UIKit/UIKit.h>
2
3 @interface SecondViewController : UIViewController
4
5 // 第一步:声明属性,用于存放传过来的值
6 @property (nonatomic, copy) NSString *contents;
7
8 @end

 第二步: 在 FirstViewController 的按钮点击方法里给 SecondViewController 的 contents 属性赋值

 1 - (void)loginButtonClick:(UIButton *)sender
 2 {
 3     // 创建对象
 4     SecondViewController *secondVC = [[SecondViewController alloc] init];
 5
 6     // 第二步:进行赋值
 7     secondVC.name = self.rootView.userTextField.text;
 8
 9     // 导航控制器push栈中
10     [self.navigationController pushViewController:secondVC animated:YES];
11 }

 第三步: 在 SecondViewController 将传过来的值显示, 使用 contents 属性给 nameLabel 赋值(在 viewDidLoad 中)

// 第三步:显示内容
self.nameLabel.text = self.name;

2. 协议传值(后面的界面给前面传值)

 第一步: 声明协议(在委托方(SecondViewController)的 .h 文件中声明)

 1 #import <UIKit/UIKit.h>
 2
 3 #warning 第一步:在SecondViewController.h里声明协议
 4 @protocol  SecondViewControllerDelegate<NSObject>
 5
 6 // 声明协议方法
 7 - (void)passValueWithString:(NSString *)textString;
 8
 9 @end
10
11 @interface SecondViewController : UIViewController
12
13 @end

 第二步: 声明代理人(在委托方(SecondViewController)的 .h 文件中声明代理人, 代理人是一个属性)

1 @interface SecondViewController : UIViewController
2
3 #warning 第二步:声明代理人
4
5 // 代理的语义设置使用assign, 防止循环引用
6 @property (nonatomic, assign) id <SecondViewControllerDelegate> secondDelegate;
7
8 @end

声明属性时的语义必须是 assign , 使用 retain , copy 会导致循环引用问题

 第三步: 执行协议方法(委托方(SecondViewController)在点击事件中使用代理属性调用代理的传值方法)

 1 // 实现点击事件方法(实现代理从后往前传值)
 2 - (void)submitButtonClick:(UIButton *)sender
 3 {
 4     // 1.把输入的内容传到第一页
 5
 6 #warning 第三步:使用代理调用代理的传值方法
 7 //    [self.secondDelegate passValueWithString:self.eatTextField.text];
 8
 9     // 判断如果代理实现了方法进行调用(安全判断,当没有方法实现时不会导致程序崩溃)
10     if ([self.secondDelegate respondsToSelector:@selector(passValueWithString:)]) {
11         [self.secondDelegate passValueWithString:self.eatTextField.text];
12     }
13
14     // 2.跳回到第一页
15     [self.navigationController popViewControllerAnimated:YES];
16 }

 第四步: 签订协议(代理人(FirstViewController)遵守协议)

1 #warning 第四步:遵守代理协议
2 @interface FirstViewController ()<SecondViewControllerDelegate>
3
4 @property (nonatomic, strong) UILabel *myLabel;
5
6 @end

 第五步: 指定代理人(在代理人(FirstViewController) 跳转到委托方的点击事件方法中指定)

 1 // 代理人的点击事件方法(跳转到委托方)
 2 - (void)rightBarClick:(UIBarButtonItem *)sender
 3 {
 4     // 1.创建视图控制器对象
 5     SecondViewController *secondVC = [[SecondViewController alloc] init];
 6
 7 #warning 第五步:设置代理人
 8     // 指定当前对象为代理人
 9     secondVC.secondDelegate = self;
10
11     // 2.push跳转
12     [self.navigationController pushViewController:secondVC animated:YES];
13 }

 第六步: 实现协议方法(代理人(FirstViewController)实现代理方法, 并接收传过来的值显示)

1 #warning 第六步:实现代理方法,并接收传过来的值
2 - (void)passValueWithString:(NSString *)textString
3 {
4     // 将传过来的值显示
5     self.myLabel.text = textString;
6 }

3. Block传值

 1> 回顾Block

 2> Block注意事项

  在 controller 中定义 Block , 实现 Block 的时候, 如果 Block 里面需要使用当前控制器对象,不可以直接使用 self , 否则会引起循环引用

  解决办法:

   ① 使用 __block 修饰变量防止循环引用(MRC)

   ② 使用 __weak 修饰变量防止循环引用(ARC)

 1     // 使用__weak修饰防止循环引用
 2 //    __weak SecondViewController *secodVC = self; // 一般写法
 3
 4     // typeof(...) 得到括号中的类型
 5     __weak typeof(self) secodVC = self; // 装逼写法
 6
 7     self.block = ^void () {
 8         NSLog(@"这事block的实现");
 9
10         secodVC.view.backgroundColor = [UIColor grayColor];
11     };

  typeof(...) 得到括号中的类型

 3> Block传值的两种方式

  方式一: 使用Block属性实现回调传值

  方式二: 在方法中定义Block实现回调传值

 4> Block属性传值

  第一步: 在传值方(SecondViewController)定义 Block 属性

1 #import <UIKit/UIKit.h>
2
3 @interface SecondViewController : UIViewController
4
5 #warning 第一步:定义Block属性
6 @property (nonatomic, copy) void(^secondBlock)(NSString *);
7
8 @end

  第二步: 在接值方(FirstViewController) 跳转到委托方的点击事件实现方法中 实现Block, 即Block回调

 1 // 跳转点击事件实现方法
 2 - (void)barClick:(UIBarButtonItem *)sender
 3 {
 4     SecondViewController *secondVC = [[SecondViewController alloc] init];
 5
 6 #warning 第二步 实现Block
 7     // Block回调
 8     secondVC.secondBlock = ^void (NSString *string) {
 9         // 得到Block回传的string,并赋值给myLabel
10         self.myLabel.text = string;
11     };
12
13     [self.navigationController pushViewController:secondVC animated:YES];
14 }

  第三步: 在传值方(SecondViewController)的返回点击事件中, 调用Block实现传值

 1 // 实现方法 进行Block传值
 2 - (void)submitButtonClick:(UIButton *)sender
 3 {
 4     // 1.Block传值
 5
 6 #warning 第三步 Block传值, 调用Block
 7     self.secondBlock(self.textField.text);
 8
 9     // 2.返回第一页
10     [self.navigationController popViewControllerAnimated:YES];
11 }

 5> 在方法中定义Block传值

 6> Block存储域

  ① 没有使用局部变量的 Block 内存存储在全局区

  ② 使用局部变量的 Block 内存存储在 栈区

  ③ 当 Block 变量定义为属性的时候, 必须使用 copy 修饰, retain无效, 即 retain 和 assign 会造成野指针问题

  当对 Block 进行 copy 操作的时候, 此时 Block 的内存区域为 堆区

  当不使用 Block 时需要使用 Block_Release() 进行销毁

时间: 2024-08-23 09:00:07

iOSDay27之界面通信的相关文章

iOS基础-UINavigationController、界面通信

UINavigationController 导航控制器 是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器 导航控制器以栈的方式管理所控制的视图控制器,至少要有一个被管理的视图控制器,这个控制器我们称作导航控制器的根视图控制器 出栈和入栈pushViewController:animated:进入下一个视图控制器 popViewControllerAnimated:返回上一个视图控制器 popToviewContro

界面通信之属性传值、代理传值

界面通信有三种方法 1.属性传值 2.代理传值 3.blcok传值 先讲讲属性和传值和代理传值 //属性传值- (void)sendValue { SecondViewController *secondVC = [[SecondViewController alloc] init]; secondVC.string = _textField.text;//这句是属性传值的核心,在需要接收值的界面声明一个字符串属性接受值 secondVC.color = self.view.background

##DAY8 界面通信

##DAY8 界面通信 注意:延展中写的东西只能在类内使用 #pragma mark ———————属性传值—————————— (第一个页面往第二个页面传值) 一.属性传值:(第一个页面往第二个页面传值) 属性传值:可以自定义属性.也可使用控件.视图的自带属性 1.属性传值用于第一个界面向第二个页面传值 2.明确两者联系的桥梁,也就是触发跳转的地方 3.明确传输的值:类型是什么 4.在第二个视图控制器内部声明相对应类型的属性,来接收传输的值 5.在第二个界面使用传入的值 注意:属性在传值中如果

UINavigationController 、界面通信

一.UINavigationController 二.定制UINavigationBar 三.界面间通信 一.UINavigationController 导航控制器,是iOS中最常用的多视图控制器之一,它用来管多个视图控制器.导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器. UINavigationController继承于UIViewController,以栈的方式管理所控制的视图控制器, 至少要有一个被管理的视图控制器,这个控制器我们称作,导航控制器的根视图控制器. 任

界面通信

属性传值.协议传值.Block传值 ?.属性传值 /**  *  属性传值     1.属性传值用于第一个界面向第二个界面传送值     2.明确二者联系的桥梁,也就是触发跳转的地方     3.明确传输的值 类型是什么     4.在第二个视图控制器内部声明相对应类型的属性,来接收传输的值     5.在第二个界面使用传入的值 */ //第?步:在SecondViewController.h?定义?个contents字符串属性来保存由第一个界面传过来的字符串内容@interface Secon

UI_08 UINavigationController、界面通信

?.UINavigationController UINavigationController:导航控制器,是iOS中最常?的多视图控制器 之?,它?来管理多个视图控制器. 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器. UINavigationController继承于UIViewController,以栈的?式管理所 控制的视图控制器,?少要有?个被管理的视图控制器,这个控制器 我们称作,导航控制器的根视图控制器. 任何继承?UIViewController的类(多态)

UI基础:UINavigationController、界面通信

UINavigationControlle UINavigationController:导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器.也称为多视图控制器. 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器. 创建: UINavigationController继承于UIViewController,以栈的形式管理所 控制的视图控制器,至少要有1个被管理的视图控制器,这个控制器 我们称作,导航控制器的根视图控制器. 任何继承于UIViewContro

iOS学习之界面通信

一.属性传值 在SecondViewController.h里 #import <UIKit/UIKit.h> @interface SecondViewController : UIViewController // 第一步:声明属性,用来存放上一页传过来的数据 @property (nonatomic, copy) NSString *contents; @end 在RootViewController.m里 - (void)loginAction { SecondViewControll

界面通信之block传值

block传值有两种方式 ?式?: 使?block属性实现回调传值 ?式?: 在?法中定义block实现回调传值 方式一比较便于理解而且常用,下面介绍方式一是如何传值的 使用block属性传值和代理传值的步骤基本上是一样的 typedef void(^BaDa)(NSString *, UIColor *); @interface SecondViewController : UIViewController @property (nonatomic, retain) UITextField *