界面传值

四种传值的方式

1、属性传值(从前往后)

步骤:

 1、属性传值用于第一个界面向第二个界面传值

 2、明确二者联系的桥梁,也就是触发跳转的地方

 3、明确传输的值,类型是什么

 4、在第二个视图控制器内部声明相对应类型的属性,来接受传输的值

 5、在第二个界面使用传入的值

 

2、代理传值(从后往前)

步骤:

1、声明协议

UI中的协议名称 为 当前类名 + Delegate

@protocol FourViewControllerDelegate<NSObject>
- (void)pushValue:(NSString *)text;
- (void)pushValue1:(UIColor *)color;
@end

 

2、声明代理

@property (nonatomic, assign) id<FourViewControllerDelegate>delegate;

 

3、让代理执行方法(在页面跳转处)

//判断代理人不为空,并且代理人响应了协议中的方法
 if (self.delegate != nil && [self.delegate respondsToSelector:@selector(pushValue:)]) {
 
        [self.delegate pushValue:self.textField.text];
        [self.delegate pushValue1:self.view.backgroundColor];
 
    }

4、指定代理人为自身

- (void)button {
    FourViewController *four = [[FourViewController alloc] init];
    //4、指定代理对象为自己
    four.delegate = self;
    [self.navigationController pushViewController:four animated:YES];
   
    
}

5、接受协议

@interface ThirdViewController : UIViewController<FourViewControllerDelegate>

6、实现协议方法

- (void)pushValue:(NSString *)text {
    _lable.text  = text;
}
 
- (void)pushValue1:(UIColor *)color{
    self.view.backgroundColor = color;
}

 

3、block传值(从后往前)

有两种方式:

一、使用block属性实现回调传值

步骤:

1、定义需要传的值得类型

typedef void (^Bada)(NSString *);
typedef void  (^Color) (UIColor *);

 

2、将Bloak声明成属性必须用copy修饰

@property (nonatomic, copy) Bada bada;
@property (nonatomic, copy) Color color;

 

3、

- (void)button {
    //执行Block
    if (self.bada != nil) {
    self.bada(self.textField.text);
    }
    
    if (self.color != nil) {
        self.color (self.view.backgroundColor);
    }
 
    [self.navigationController popToRootViewControllerAnimated:YES];
    
}

4、对block进行实现

SecondViewController *second = [[SecondViewController alloc] init];
    
    second.bada = ^(NSString *str) {
        self.lable.text = str;
    };
    second.color = ^(UIColor *color) {
        self.view.backgroundColor = color;
    };
    [self.navigationController pushViewController:second animated:YES];

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

步骤:

1、在First.h文件中,重定义void(^)(NSString *string)类型 的别名为FirstBlock
typedef void(^FirstBlock)(NSString *string); 

2、声明方法,在方法中封装block 

-(void)sendNumber:(NSInteger )number andBlock: (FirstBlock)block; 

 

3、在First.m实现 法,并执 block

 -(void)sendNumber:(NSInteger )number andBlock: (FirstlBlock)block;

    NSString *string = [NSString

stringWithFormat:@"%ld",number];

    block(string);

}

4、 执行放法,实现block并接收回传过来的string值 

First*first= [First alloc] init];
 //执行方法
[first sendNumber:12243432 andBlock:^(NSString 
*string) {
        self.label.text = string;
}];

4、单例传值(可用于从第一页面直接传值给第十个页面,既可以从前往后,也可以从后往前)

步骤:

1、创建一个类继承自NSObject,在.h文件中声明一个类方法。

//单利方法是类方法, 返回值类型为instancetype

//自己定义的单例类,方法名通常都是以share开头

+ (instancetype)shareInstance;

2、在.m文件中写类方法的实现

static Handler *handler = nil;
 
@implementation Handler
 
//怎么保证 创建的 当刘对象是唯一的?
+ (instancetype)shareInstance {
    
    @synchronized(self) {//加锁,保证创建过程同一时间内只允许一个线程对象访问,保证其唯一性(self 任意对象)
        
    if (handler == nil) {
       handler = [[Handler alloc] init];
    }
        
    }
    return handler;
    
}

3、借助视图的即将出现和即将消失的方法,可以实现值得传递。(注意视图的加载和创建方法只会走一次,但是视图的将出现和即将消失的方法会走多次)

- (void)viewWillDisappear:(BOOL)animated {
    //创建单例
    Handler *handler = [Handler shareInstance];
    handler.string= self.textField.text;
}
- (void)viewWillAppear:(BOOL)animated {
    Handler *handler = [Handler shareInstance];
    self.textField.text = handler.string;
}