常见的四种传值方式:
单例, 属性, block, delegate
首先让我们创建一个根视图RootViewController
self.view.backgroundColor = [UIColor colorWithRed:0.967 green:0.895 blue:1.000 alpha:1.000];
PropertyViewController *propertyVC = [[PropertyViewController alloc] init];
UINavigationController *propertyNC = [[UINavigationController alloc] initWithRootViewController:propertyVC];
propertyNC.tabBarItem.title = @"属性";
DelegateViewController *delegateVC = [[DelegateViewController alloc] init];
UINavigationController *delegateNC = [[UINavigationController alloc] initWithRootViewController:delegateVC];
delegateNC.tabBarItem.title = @"代理";
BlockViewController *blockVC = [[BlockViewController alloc] init];
UINavigationController *blockNC = [[UINavigationController alloc] initWithRootViewController:blockVC];
blockNC.tabBarItem.title = @"Block";
SingletonViewController *singletonVC = [[SingletonViewController alloc] init];
UINavigationController *singletonNC = [[UINavigationController alloc] initWithRootViewController:singletonVC];
singletonNC.tabBarItem.title = @"单例";
self.viewControllers = @[propertyNC, delegateNC, blockNC, singletonNC];
[singletonVC release];
[singletonNC release];
[blockNC release];
[blockVC release];
[delegateNC release];
[delegateVC release];
[propertyNC release];
[propertyVC release];
Singleton *singleton = [Singleton defaultSingleton];
singleton.string = @"七夕快乐,单身狗们";
***********************再次我们开始学习代理传值************************************
*******************************代理传值是后一个页面向前一个页面传值*******************************
所以要创建第一个页面
DelegateViewController:
#import "DelegateViewController.h"
#import "DelegateDetailViewController.h"
@interface DelegateViewController ()<DelegateDetailViewControllerDelegate> {
UILabel *label;
}
@end
@implementation DelegateViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:1.000 green:0.981 blue:0.868 alpha:1.000];
self.navigationItem.title = @"代理";
//创建一个label
label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.textColor = [UIColor blackColor];
label.font = [UIFont boldSystemFontOfSize:40];
[self.view addSubview:label];
[label release];
//创建一个button
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(140, 144, 100, 100);
[button setTitle:@"下一个" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:20];
button.tintColor = [UIColor colorWithWhite:0.000 alpha:0.540];
button.layer.borderWidth = 10;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.layer.cornerRadius = 50;
button.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.770];
[button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
//button关联的方法
- (void)pressButton:(UIButton *)button {
//推到下一个页面
DelegateDetailViewController *delegateDVC = [[DelegateDetailViewController alloc] init];
[self.navigationController pushViewController:delegateDVC animated:YES];
//设置代理
delegateDVC.delegate = self;
[delegateDVC release];
}
#pragma mark - DelegateDetailViewControllerDelegate
//执行代理方法
- (void)viewController:(DelegateDetailViewController *)viewController passValue:(NSString *)string {
//传值
label.text = string;
}
@end
后一个页面.h文件
#import <UIKit/UIKit.h>
@class DelegateDetailViewController;
//设置代理方法
@protocol DelegateDetailViewControllerDelegate <NSObject>
//协议
- (void)viewController:(DelegateDetailViewController *)viewController passValue:(NSString *)string;
@end
@interface DelegateDetailViewController : UIViewController
//delegate属性使用assign,避免出现保留环(retain cycle),导致双方都持有对方,从而得不到释放
@property (nonatomic,assign) id<DelegateDetailViewControllerDelegate> delegate;
@end
后一个页面.m文件
//
// DelegateDetailViewController.m
// LessonPassValue
//
// Created by lanouhn on 15/8/19.
// Copyright (c) 2015年 chaogege. All rights reserved.
//
#import "DelegateDetailViewController.h"
#import "DelegateViewController.h"
@interface DelegateDetailViewController (){
UITextField *textField ;
}
@end
@implementation DelegateDetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blackColor];
textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 84, 335, 40)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"请输入你想传的值";
[self.view addSubview:textField];
[textField release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(140, 144, 100, 100);
[button setTitle:@"返回" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:20];
button.tintColor = [UIColor colorWithWhite:0.000 alpha:0.540];
button.layer.borderWidth = 10;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.layer.cornerRadius = 50;
button.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.770];
[button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.text = @"代理传值,后一个给前一个传值";
label.textColor = [UIColor whiteColor];
[self.view addSubview:label];
[label release];
}
- (void)pressButton:(UIButton *)button {
//先判断该代理是否具有执行代理方法的能力, 有的话, 执行该方法
if ([self.delegate respondsToSelector:@selector(viewController:passValue:)]) {
[self.delegate viewController:self passValue:textField.text];
}
//返回上一个页面
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
************************************单例传值:多个页面间传值*********************************
第一个页面
//
// DelegateDetailViewController.m
// LessonPassValue
//
// Created by lanouhn on 15/8/19.
// Copyright (c) 2015年 chaogege. All rights reserved.
//
#import "DelegateDetailViewController.h"
#import "DelegateViewController.h"
@interface DelegateDetailViewController (){
UITextField *textField ;
}
@end
@implementation DelegateDetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blackColor];
textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 84, 335, 40)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"请输入你想传的值";
[self.view addSubview:textField];
[textField release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(140, 144, 100, 100);
[button setTitle:@"返回" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:20];
button.tintColor = [UIColor colorWithWhite:0.000 alpha:0.540];
button.layer.borderWidth = 10;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.layer.cornerRadius = 50;
button.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.770];
[button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.text = @"代理传值,后一个给前一个传值";
label.textColor = [UIColor whiteColor];
[self.view addSubview:label];
[label release];
}
- (void)pressButton:(UIButton *)button {
if ([self.delegate respondsToSelector:@selector(viewController:passValue:)]) {
[self.delegate viewController:self passValue:textField.text];
}
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
第二个页面.h文件
#import <Foundation/Foundation.h>
@interface Singleton : NSObject
@property (nonatomic, retain) NSString *string;
+ (Singleton *)defaultSingleton;
@end
第二个文件.m文件
#import "Singleton.h"
@implementation Singleton
- (void)dealloc
{
self.string = nil;
[super dealloc];
}
//重写单例创建方法, 保证其唯一性
static Singleton *singleton = nil;
+ (Singleton *)defaultSingleton {
if (singleton == nil) {
singleton = [[Singleton alloc] init];
}
return singleton;
}
@end
***************************************属性传值:前一个页面向后一个页面传值******************************************
//
// PropertyViewController.m
// LessonPassValue
//
// Created by lanouhn on 15/8/19.
// Copyright (c) 2015年 chaogege. All rights reserved.
//
#import "PropertyViewController.h"
#import "PropertyDetailViewController.h"
@interface PropertyViewController () {
UITextField *textField;
}
@end
@implementation PropertyViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.210];
self.navigationItem.title = @"属性";
textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 84, 335, 40)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"请输入你想传的值";
[self.view addSubview:textField];
[textField release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(140, 144, 100, 100);
[button setTitle:@"传值" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:20];
button.tintColor = [UIColor colorWithWhite:0.000 alpha:0.540];
button.layer.borderWidth = 10;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.layer.cornerRadius = 50;
button.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.770];
[button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.text = @"属性传值,前一个给后一个传值";
[self.view addSubview:label];
[label release];
}
- (void)pressButton:(UIButton *)button {
PropertyDetailViewController *propertyDetailVC = [[PropertyDetailViewController alloc] init];
propertyDetailVC.string = textField.text;
[self.navigationController pushViewController:propertyDetailVC animated:YES];
[propertyDetailVC release];
}
@end
后一个页面.h文件
#import <UIKit/UIKit.h>
@interface PropertyDetailViewController : UIViewController
@property (nonatomic, retain) NSString *string;
@end
后一个页面.m文件
//
// PropertyDetailViewController.m
// LessonPassValue
//
// Created by lanouhn on 15/8/19.
// Copyright (c) 2015年 chaogege. All rights reserved.
//
#import "PropertyDetailViewController.h"
@interface PropertyDetailViewController ()
@end
@implementation PropertyDetailViewController
- (void)dealloc
{
self.string = nil;
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blackColor];
self.navigationItem.title = @"属性详情";
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.textColor = [UIColor whiteColor];
label.text = self.string;
label.font = [UIFont boldSystemFontOfSize:40];
[self.view addSubview:label];
[label release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
**********************block传值:属性传值能用的地方block就能用****************************
第一个文件
//
// BlockViewController.m
// LessonPassValue
//
// Created by lanouhn on 15/8/19.
// Copyright (c) 2015年 chaogege. All rights reserved.
//
#import "BlockViewController.h"
#import "BlockDetailViewController.h"
@interface BlockViewController () {
UILabel *label;
}
@end
@implementation BlockViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor colorWithRed:0.730 green:0.869 blue:1.000 alpha:1.000];
self.navigationItem.title = @"Block";
void (^blockName)(NSString *) = ^(NSString *string) {
NSLog(@"Hello,%@!", string);
};
blockName(@"苍老师");
//block传值
//注:只要能用delagate传值的都可以用block传值
//从后一个页面向前一个页面传值
//步骤
//1.在后一个页面重命名block类型,写block属性,调用block
//2.在前一个页面,给block赋值
//3.优化:把block赋值封装起来,重命名类型时要加参数名
label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.textColor = [UIColor blackColor];
label.font = [UIFont boldSystemFontOfSize:40];
[self.view addSubview:label];
[label release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(140, 144, 100, 100);
[button setTitle:@"下一个" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:20];
button.tintColor = [UIColor colorWithWhite:0.000 alpha:0.540];
button.layer.borderWidth = 10;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.layer.cornerRadius = 50;
button.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.770];
[button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)pressButton:(UIButton *)button {
BlockDetailViewController *blockDVC = [[BlockDetailViewController alloc] init];
//接收值
//方法1.
/*
blockDVC.block = ^(NSString *string){
label.text = string;
};
*/
//方法2:
[blockDVC passValue:^(NSString *string) {
label.text = string;
}];
[self.navigationController pushViewController:blockDVC animated:YES];
[blockDVC release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
第二个文件.h
#import <UIKit/UIKit.h>
//block类型的参数个数,由传值的个数决定
//block类型中的参数类型,由传值参数的类型决定
typedef void (^BlockType)(NSString *string);
@interface BlockDetailViewController : UIViewController
//block默让是在栈区存储的,使用copy能把他从栈区拷贝到堆区
@property (nonatomic, copy) BlockType block;
//block赋值的封装
- (void)passValue:(BlockType)block;
@end
第二个文件.m文件
//
// BlockDetailViewController.m
// LessonPassValue
//
// Created by lanouhn on 15/8/19.
// Copyright (c) 2015年 chaogege. All rights reserved.
//
#import "BlockDetailViewController.h"
#import "BlockViewController.h"
@interface BlockDetailViewController () {
UITextField *textField;
}
@end
@implementation BlockDetailViewController
- (void)dealloc
{
self.block = nil;
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor colorWithWhite:0.883 alpha:1.000];
textField = [[UITextField alloc] initWithFrame:CGRectMake(20, 84, 335, 40)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = @"请输入你想传的值";
[self.view addSubview:textField];
[textField release];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(140, 144, 100, 100);
[button setTitle:@"返回" forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:20];
button.tintColor = [UIColor colorWithWhite:0.000 alpha:0.540];
button.layer.borderWidth = 10;
button.layer.borderColor = [UIColor whiteColor].CGColor;
button.layer.cornerRadius = 50;
button.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.770];
[button addTarget:self action:@selector(pressButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 204, 335, 200)];
label.numberOfLines = 0;
label.text = @"block传值,前一个给后一个传值";
label.textColor = [UIColor blackColor];
[self.view addSubview:label];
[label release];
}
- (void)pressButton:(UIButton *)button{
self.block(textField.text);
[self.navigationController popViewControllerAnimated:YES];
}
//block封装方法的实现
- (void)passValue:(BlockType)block{
self.block = block;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end