iOS 界面传值的方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/blog_DreamFly/article/details/79401306

常见的有6种,可分为正向传值、反向传值、跨界面传值;

1.属性

只适用于正向传值,A页面跳转到B页面;
在A控制器界面中

BViewController *vc =  [BViewController alloct] init];
vc.title = @"需要传递的值";

2.单例

即可以正向传值、也可以反向传值、又能跨界面传值;
单例类只需实例化一次,有且仅有一个单例对象;
OC中常见的单例类:

  • AppDelegate
  • NSUserDefaults
  • NSNotification
  • NSFileManager

3.代理传值

反向传值,B页面跳转回A页面;
组成部分:

  • 委托方:规定协议内容,持有协议;
  • 代理方:遵守协议,并实现协议方法;
  • 协议:通信规则,委托方和代理方通信的纽带;

声明协议的关键字是@protocol,修饰协议方法的关键字:
@required:必须实现的方法 ;
@optional:可实现、可不实现的的方法;

(1).在B控制器界面.h文件中,声明自己的协议;

@protocol BViewControllerDelegate <NSObject>
- (void)sendUsername:(NSString *)username password:(NSString *)password; 
@end

@interface BViewController : UIViewController
// 声明属性,注意weak修饰
@property (nonatomic, weak) id <BViewControllerDelegate> delegate; 
@end

在B控制器界面.m文件中

// 赋值
[self sendUsername:_usernameTextField.text password:_passwordTextField.text];
[self.navigationController popToRootViewControllerAnimated:YES];

(2)在A控制器界面;

//  遵守B协议
@interface AViewController ()<BViewControllerDelegate>
@property (nonatomic, strong) UILabel *usernameLabel;
@property (nonatomic, strong) UILabel *passwordLabel;
@end

// 控制器跳转,设置代理
BViewController *vc = [[BViewController alloc] init];
// 设置B的代理
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];


// 实现代理方法
#pragma mark - ——————————— BViewControllerDelegate ——————————— 
- (void)sendUsername:(NSString *)username password:(NSString *)password
 {
     self.usernameLabel.text = username;
     self.passwordLabel.text = password;
 }

4.block传值

代理能实现的,block基本上都可以实现,并且比代理使用起来简单;
关键字copy声明,B页面跳转回A页面;
(1).在B控制器中

 // 别名表示
typedef void(^ReturnIDCardInfoBlock)(NSString *name, NSString *sex);
// .h文件中声明为属性,注意copy修饰
@property (nonatomic, copy) ReturnIDCardInfoBlock returnIDCardInfoBlock;


//  .m实现文件中存值
self.returnIDCardInfoBlock(self.nameTextField.text, self.sexTextField.text);

(2).在A控制器中

BViewController *vc = [[BViewController alloc] init];
vc.returnIDCardInfoBlock = ^(NSString *name, NSString *sex) {
    _name = name;
    _sex= sex;
};
[self.navigationController pushViewController:vc animated:YES];
1"强弱引用"
修饰强引用的关键字'__strong',简单理解为:强制持有对象,对象的引用计数+1;
修饰弱引用关键字'__weak',简单理解为:不持有对象,对象的引用计数不变;
如果【block内部】使用了【外部声明的强引用】访问【对象A】,那么【block内部】会自动产生于一个【强引用】指向【对象A;
如果【block内部】使用了【外部声明的弱引用】访问【对象A】,那么【block内部】会自动产生于一个【弱引用】指向【对象A;2"循环引用"
简单理解为:A对象持有B对象的同时,B对象又持有A,导致A、B都无法释放;

5.通知传值

跨界面传值
(1).在需要传值的界面

NSDictionary *dic = @{@"username":self.usernameTextField.text, @"password":self.passwordTextField.text};
// 发送通知(传值)
[[NSNotificationCenter defaultCenter] postNotificationName:@"userLoginNotification" object:nil userInfo:dic];

(2).接受值的界面

// 注册通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userLogin:) name:@"userLoginNotification" object:nil];

// 实现通知的方法(接收值)
- (void)userLogin:(NSNotification *)notification
{
    NSLog(@"接收到通知");
    NSLog(@"%@",notification.userInfo[@"username"]);
    NSLog(@"%@",notification.userInfo[@"password"]);
}

// 移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"userLoginNotification" object:nil];

6.NSUserdefault

既可以正向传值,也可以反向传值,多用于跨界面传值;
是写入沙盒,以文件的形式进行传值;

//  存值
[[NSUserDefaults standardUserDefaults] setValue:self.usernameTextField.text forKey:@"username"];
[[NSUserDefaults standardUserDefaults] synchronize] ;

// 取值
NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:@"username"];
注意:键值对key的唯一性; 

猜你喜欢

转载自blog.csdn.net/blog_DreamFly/article/details/79401306
今日推荐