1、属性传值

前向后传值。

记住:

/*

1: 属性传值*步需要用到什么类型就定义什么样的属性

2: 从上一个页面到一个页面的选中方法里面将要传的值传到来(上一个页面)备注:这种方法只适用于上一个页面推到下一个页面

*/

MainViewController与SecondViewController两个视图 控制器 ,点击MainViewController中的按钮将跳转到SecondViewController视图,同时想要传递一个值过去。这时可以利用属性传值。

首先SecondViewController视图中需要有一个属性用来 存储 传递过来的值:

@property(nonatomic,retain) NSString *firstValue ;//属性传值

然后MainViewController视图需要引用SecondViewController视图的头文件,在视图中的按钮点击事件中,通过SecondViewController的对象将需要传递的值存在firstValue中:

(void)buttonAction:(UIButton *)button
{
SecondViewController *second = 
[[SecondViewController alloc]init];//用下一个视图的属性接受想要传过去的值,属性传值
second.firstValue = _txtFiled.text;
[self.navigationController pushViewController:second animated:YES];
}

页面跳转之后,就能在SecondViewController视图中,通过存值的属性,取用刚才传递过来的值:

//显示传过来的值[_txtFiled setText:_firstValue];//firstValue保存传过来的值

2、方法传值:

需求同一中的 属性传值 一样,但是要通过使用方法传值,可以直接将方法与初始化方法合并,此时当触发MainViewController的按钮点击事件并跳转到 SecondViewController时,在按钮点击事件中可以直接通过SecondViewController的初始化,将值保存在 firstValue中:

初始化方法如下:                首先SecondViewController视图中需要有一个属性用来 存储 传递过来的值:

@property(nonatomic,retain) NSString *firstValue ;//传值用

 

//重写初始化方法,用于传值
- (id)initWithValue:(NSString *)value
{
if(self = [super initWithNibName:nil bundle:nil]) {
                 self.firstValue = value;
            }
        return self;
}

方法传值:

 

- (void)buttonAction:(UIButton *)button
{//将方法传值与初始化写到一起
SecondViewController *second = [[SecondViewController alloc]
initWithValue:_txtFiled.text];//此时已经将值存在firstValue中
[self.navigationController pushViewController:second animated:YES];
}

这样就可以直接通过firstValue属性获得传递过来的值:

 

//显示传过来的值[_txtFiled setText:_firstValue];//firstValue保存传过来的值

3、协议传值   代替协议代理传值,主要时间点问题。

上面 中说明了如何从A传值到B,这次要讲的是如何从A进入B,在B输入值后回传给A,这类似于Android中的利用 Activity的onActivityResult回调方法实现两个Activity之间的值传递,那么在IOS中如何实现这个功能呢,答案是使用 Delegate(委托协议)。

工程结构如下:

1346122481_1896.png

其中有两个ViewController分别对应两个界面,一个协议PassValueDelegate用来实现传值协议,UserEntity是传递数据的对象。
以下是实现的效果:点击Open进入Second界面,输入完毕点击OK后回到First界面并显示结果

1346122704_8626.png   1346122709_1735.png

1346122728_4358.png

协议中声明的方法:

copy
  1. #import <Foundation/Foundation.h>
  2. @ class  UserEntity;
  3. @protocol PassValueDelegate <NSObject>
  4. -( void )passValue:(UserEntity *)value;
  5. @end
  6. 在*个窗口实现协议:
  1. #import <UIKit/UIKit.h>
  2. #import “PassValueDelegate.h”
  3. //*个窗口遵守PassValueDelegate
  4. @interface ViewController : UIViewController<PassValueDelegate>
  5. @property (retain, nonatomic) IBOutlet UILabel *nameLabel;
  6. @property (retain, nonatomic) IBOutlet UILabel *ageLabel;
  7. @property (retain, nonatomic) IBOutlet UILabel *gendarLabel;
  8. – (IBAction)openBtnClicked:(id)sender;
  9. @end

.m文件中实现协议的方法:

[cpp]view plaincopy

  1. //实现协议,在*个窗口显示在第二个窗口输入的值方法
  2. -( void )passValue:(UserEntity *)value
  3. {
  4.     self.nameLabel.text = value.userName;
  5.     self.ageLabel.text = [NSString stringWithFormat:@ “%d” ,value.age];
  6.     self.gendarLabel.text = value.gendar;
  7. }

点击Open按钮所触发的事件:

[cpp]view plaincopy

  1. //点击进入第二个窗口的方法
  2. – (IBAction)openBtnClicked:(id)sender {
  3.     SecondViewController *secondView = [[SecondViewController alloc] initWithNibName:@ “SecondViewController”  bundle:[NSBundle mainBundle]];
  4.      //设置第二个窗口中的delegate为*个窗口的self
  5.     secondView.delegate = self;
  6.     [self.navigationController pushViewController:secondView animated:YES];
  7. }

第二个窗口中声明一个NSObject对象,该对象遵守PassValueDelegate协议:

[cpp]view plaincopy

  1. #import <UIKit/UIKit.h>
  2. #import “PassValueDelegate.h”
  3. @interface SecondViewController : UIViewController
  4. @property (retain, nonatomic) IBOutlet UITextField *nameTextField;
  5. @property (retain, nonatomic) IBOutlet UITextField *ageTextFiled;
  6. @property (retain, nonatomic) IBOutlet UITextField *gendarTextField;
  7. //这里用assign而不用retain是为了防止引起循环引用。
  8. @property(nonatomic,assign) NSObject<PassValueDelegate> *delegate;
  9. – (IBAction)okBtnClicked:(id)sender;
  10. – (IBAction)closeKeyboard:(id)sender;
  11. @end

输入完毕后,点击OK按钮所触发的事件:

[cpp]view plaincopy

  1. – (IBAction)okBtnClicked:(id)sender {
  2.     UserEntity *userEntity = [[UserEntity alloc] init];
  3.     userEntity.userName = self.nameTextField.text;
  4.     userEntity.gendar = self.gendarTextField.text;
  5.     userEntity.age = [self.ageTextFiled.text intValue];
  6.      //通过委托协议传值
  7.     [self.delegate passValue:userEntity];
  8.      //退回到*个窗口
  9.     [self.navigationController popViewControllerAnimated:YES];
  10.     [userEntity release];
  11. }

以上就实现了使用Delegate在两个ViewController之间传值,这种场景一般应用在进入子界面输入信息,完后要把输入的信息回传给前一个界面的情况,比如修改用户个人信息,点击修改进入修改界面,修改完后到显示界面显示修改后的结果。

4、Block传值                                               //参考 http://liuyafang.blog.51cto.com/8837978/1551399

1.*页中 声明一个 block, 需要传入一个颜色 , 让当前的 view 变色

// 声明一个 block, 需要传入一个颜色 , 让当前的 view 变色

void (^changeColor)( UIColor *color) = ^( UIColor *color){

self . view . backgroundColor = color;

};

2 .  *页中 //block 传值 ——— 将 block 给第二个页面

SecondViewController *secondVC = [[ SecondViewController   alloc ]  init ];

//block 传值 ——— 将 block 给第二个页面

secondVC. block = changeColor;

3.第二页中定义 — 当 block 变量作为一个类的属性 , 必须要使用 copy 修饰

//block 传值 ——— 将 block 给第二个页面

//block 传值 — 当 block 变量作为一个类的属性 , 必须要使用 copy 修饰

@property ( nonatomic  ,  copy ) void (^block)( UIColor  *color);

4.在第二页中给block传值

//block 传值 ——— 将传值给 block

NSArray  *array = [ NSArray   arrayWithObjects :[ UIColor   yellowColor ], [ UIColor   cyanColor ], [ UIColor   greenColor ], [ UIColor   brownColor ],  nil ];

self . block ([array  objectAtIndex : rand () %  4 ]);

类和文件

AppDelegate.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#import "AppDelegate.h"

#import "MainViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// Override point for customization after application launch.

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

 

MainViewController *mainVC = [[MainViewController alloc] init];

UINavigationController *navVc = [[UINavigationController alloc] initWithRootViewController:mainVC];

self.window.rootViewController = navVc;

//模糊效果

navVc.navigationBar.translucent = YES;

[navVc release];

[mainVC release];

 

 

 

 

[_window release];

return YES;

}

- (void)dealloc

{

[_window release];

[ super dealloc];

}

- (void)applicationWillResignActive:(UIApplication *)application

{

// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

}

- (void)applicationDidEnterBackground:(UIApplication *)application

{

// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

}

- (void)applicationWillEnterForeground:(UIApplication *)application

{

// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.

}

- (void)applicationDidBecomeActive:(UIApplication *)application

{

// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

}

- (void)applicationWillTerminate:(UIApplication *)application

{

// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

}

@end

MainViewController.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

#import "MainViewController.h"

#import "SecondViewController.h"

@interface MainViewController ()

@end

@implementation MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self = [ super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

// Custom initialization

}

return self;

}

- (void)viewDidLoad

{

[ super viewDidLoad];

// Do any additional setup after loading the view.

self.title = @ "block传值" ;

UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];

button.frame = CGRectMake(120, 100, 80, 30);

button.backgroundColor = [UIColor magentaColor];

[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

[button setTitle:@ "按钮" forState:UIControlStateNormal];

button.layer.cornerRadius = 5;

[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

}

- (void)buttonClicked:(UIButton *)button

{

//block语法

//返回值类型 (^block参数名) (参数类型 参数名) = ^返回值类型 (参数类型 参数名) {

//具体实现;

//};

 

float b = 0;

 

//1.无参数无返回值

void(^block1)(void) = ^(void){

NSLog(@ "可口可乐" );

};

//block语法调用

block1();

 

 

//2.有参数,无返回值

void(^block2)(NSString *str1, NSString *str2) = ^void(NSString *str1, NSString *str2){

NSString *a = [str1 stringByAppendingString:str2];

NSLog(@ "%@" , a);

};

block2(@ "abc" ,@ "def" );

 

 

//3.有返回值,无参数

NSString *(^block3)(void) = ^NSString *(void){

return @ "咿呀咿呀呦" ;

};

NSLog(@ "%@" ,block3());

//4.有参数,有返回值

NSString *(^block4)(NSString *str1) =^NSString *(NSString *str1){

return [str1 stringByAppendingString:@ "真棒!!!!" ];

};

NSLog(@ "%@" , block4(@ "苹果电脑" ));

 

//声明一个block,需要传入一个颜色,让当前的view变色

void(^changeColor)(UIColor *color) = ^(UIColor *color){

self.view.backgroundColor = color;

};

//block传值------------声明一个

void(^changeValue)(UITextField *textField) = ^void(UITextField *textField){

[button setTitle:textField.text forState:UIControlStateNormal];

};

NSLog(@ "%@" , block1); //block的地址在全局区

NSLog(@ "%@" , changeColor); //如果在block的代码中,使用了block外部的变量,系统会把block指针转移到栈区

 

SecondViewController *secondVC = [[SecondViewController alloc] init];

//block传值---------将block给第二个页面

secondVC.block = changeColor;

secondVC.blockofValue = changeValue;

secondVC.name = button.currentTitle;

NSLog(@ "%@" , button.currentTitle);

NSLog(@ "%@" , secondVC.block); //使用copy后block会被系统转移到堆区

[self.navigationController pushViewController:secondVC animated:YES];

[secondVC release];

}

- (void)didReceiveMemoryWarning

{

[ super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

/*

#pragma mark - Navigation

{

// Get the new view controller using [segue destinationViewController].

// Pass the selected object to the new view controller.

}

*/

@end

SecondViewController.h

1
2
3
4
5
6
7
8
9

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

@property (nonatomic , copy)void(^block)(UIColor *color);

@property (nonatomic , copy)void(^blockofValue)(UITextField *textField);

//

@property (nonatomic , copy)NSString *name;

@end

SecondViewController.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

import "SecondViewController.h"

@interface SecondViewController ()

@property (nonatomic , retain)UITextField *textField;

@end

@implementation SecondViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

self = [ super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

// Custom initialization

}

return self;

}

- (void)viewDidLoad

{

[ super viewDidLoad];

// Do any additional setup after loading the view.

self.view.backgroundColor = [UIColor whiteColor];

self.textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 220, 30)];

self.textField.borderStyle = UITextBorderStyleRoundedRect;

//

self.textField.text = self.name;

NSLog(@ "%@" ,self.name);

self.textField.clearButtonMode = UITextFieldViewModeAlways;

[self.view addSubview:self.textField];

[_textField release];

 

 

UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 180, 120, 30)];

button.backgroundColor = [UIColor cyanColor];

[button setTitle:@ "点击" forState:UIControlStateNormal];

button.layer.cornerRadius = 5;

[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

}

- (void)buttonClicked:(UIButton *)button

{

//block传值---------将传值给block

NSArray *array = [NSArray arrayWithObjects:[UIColor yellowColor], [UIColor cyanColor], [UIColor greenColor], [UIColor brownColor], nil];

self.block([array objectAtIndex:rand() % 4]);

//block传值---------将传值给block

self.blockofValue(self.textField);

[self.navigationController popToRootViewControllerAnimated:YES];

}

- (void)didReceiveMemoryWarning

{

[ super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

/*

#pragma mark - Navigation

{

// Get the new view controller using [segue destinationViewController].

// Pass the selected object to the new view controller.

}

*/

@end

5 单例 传值

单例只会对某个类实例化一次/单例类,对单例这个类实例化一次有且仅有一个对象

你单例初始化,只能初始化一次,然后你指向的对象,其实都是指向一个内存地址,也就是同一块内存,所以都是一样的/

那么,只能有一个对象,就是实例化的那个

(1)定义单例类singleton      .h文件

#import <Foundation/Foundation.h>

@interface singleton : NSObject  //步骤一

//@property (strong,nonatomic) UITextField *value;//*开始的时候把这个value定义为UITextField了,然后在init里面又没有初始化它,就取不到值。任何对象都要初始化它才能使用。

@property (strong, nonatomic) NSString *value;

//+(id)shareData:

+(singleton *)shareData;  //步骤二

@end

//.m文件

#import “singleton.h”

@implementation singleton

 

static singleton *singletonData = nil;  //步骤三

+(singleton *)shareData {  //步骤四

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

singletonData = [[singleton alloc] init];

});

return singletonData;

}

-(id)init {  //步骤五

if (self = [super init]) {

//        self.value = [[UITextField alloc]init];

}

return self;

}

@end

//以上是一个完整单例子

(2)ViewController

#import <UIKit/UIKit.h>

#import “OneViewController.h”

#import “singleton.h”   //引用单例

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *qqTextfield;

– (IBAction)go:(id)sender;

@end

– (IBAction)go:(id)sender {

//单例的使用

singleton *oneS = [singleton shareData];

//    oneS.value.text = self.qqTextfield.text;

oneS.value = self.qqTextfield.text;

OneViewController *oneVC = [[OneViewController alloc]init];

[self presentViewController:oneVC animated:YES completion:nil];

}

(3)OneViewController

#import <UIKit/UIKit.h>

#import “singleton.h”

@interface OneViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *oneTextField;

@end

– (void)viewDidLoad

{

[super viewDidLoad];

// Do any additional setup after loading the view from its nib.

self.oneTextField.text = [singleton shareData].value;

}

6:数据共享。

OS app之间要共享数据不是那么容易,因为每个app都是sandbox。然后,有时候又不得不跟其它app之间共享数据,那应该怎么办呢?

下面是一些常用方法的总结:

  •  

    UIDocumentInteractionController

    Availability: iOS 3.2+

    具体用法参见: http://mobile.tutsplus.com/tutorials/iphone/previewing-and-opening-documents-with-uidocumentinteractioncontroller/

  • UIActivityViewController
    Availability: iOS 6.0+
  • Shared Keychain Access
    这个要求app之间用的是同样的证书
  • Custom URL Scheme
    通过构造URL,把数据作为参数传递过去。 本地测试过,传递10000个字符都可以,不过不要太长,内存可能吃不消。
  • Web Service 通过dropbox或者其他第三方的服务来共享数据。
  • UIPasteboard + URL Scheme 通过URL scheme传递UIPasteboard的名称,然后通过UIPasteboard共享数据。
    微信iOS SDK应该采用的就是这种方式。
    不过在iOS 7上,这种方法会存在问题,如果采用这种方案,得赶紧想办法解决。

1)  http://enharmonichq.com/sharing-data-locally-between-ios-apps/

2)  http://stackoverflow.com/questions/17080074/ios7-beta-doesnt-allow-inter-app-communication-by-uipasteboard

 

7:通知传值

通知中心
NSNotificationCenter提供了一种更加解耦的方式。*典型的应用就是任何对象对可以发送通知到中心,同时任何对象可以监听中心的通知。
发送通知的代码如下:

[[NSNotificationCenter defaultCenter] postNotificationName:@”myNotificationName” object:broadcasterObject];
注册接收通知的代码如下:

[[NSNotificationCenter defaultCenter] addObserver:listenerObject selector:@selector(receivingMethodOnListener:) name:@”myNotificationName” object:nil];
注册通知的时候可以指定一个具体的广播者对象,但这不是必须的。你可能注意到了defaultCenter 。实际上这是你在应用中会使用到的唯一的中心。通知会向整个应用开放,因此只有一个中心。
同时还有一个NSDistributedNotificationCenter。这是用来应用间通信的。在整个计算机上只有一个该类型的中心。
优点: 通知的发送者和接受者都不需要知道对方。可以指定接收通知的具体方法。通知名可以是任何字符串。
缺点: 较键值观察需要多点代码。在删掉前必须移除监听者。 不能传大量数值,只能让谁去做什么事。