iOS-跨界面傳值和跨應用傳值


跨界面傳值

從一個界面將一個結果值傳到另一個界面,這個是我們在開發過程中非常常見的一個問題。傳值本身並不是一個太復雜的問題,在此主要簡述一下常用的傳值方法。

我們傳值常用的方法主要有四種:

  • 1.屬性傳值
  • 2.代理傳值
  • 3.block傳值
  • 4.通知傳值
  • 5.KVO
  • 對象傳值

屬性傳值:

屬性傳值應該來說是比較簡單的一種傳值方式,但是這種傳值方式有其局限性,常用的一種場合是我們從界面A跳轉到界面B,如何我們想講界面A的值傳到界面B,屬性傳值是比較方便的一種方式。如下圖所示,如果我們點擊A界面上的一個按鈕,跳轉到B界面,並且把A界面的一個值傳送到B界面。

先說明一下大致的原理,首先要創建兩個控制器A和B,在A中導入B的頭文件,在A的按鈕點擊事件中,添加A跳轉到B的代碼段。現在的問題是如何在跳轉的過程中把A界面上的值傳到B界面呢?

我們可以給B添加一個屬性,在點擊按鈕從A跳轉到B的時候,將A界面要傳送的值賦給B的屬性,這樣在B界面可以使用(self.屬性)直接獲取從A界面傳過來的值。

代碼段如下:(下面的代碼段是一個最簡單的演示)

 

1 #import <UIKit/UIKit.h>
2 
3 @interface ViewController : UIViewController
4 {
5     NSString *send;//我們在界面跳轉的時候,將send的值傳到下一個界面
6 }
7 - (IBAction)changeScreenButtonClick:(UIButton *)sender;
8 @end
A.h
 1 #import "ViewController.h"
 2 #import "BViewController.h"
 3 @interface ViewController ()
 4 
 5 @end
 6 
 7 @implementation ViewController
 8 
 9 - (void)viewDidLoad
10 {
11     [super viewDidLoad];
12     // Do any additional setup after loading the view, typically from a nib.
13     send = @"傳值操作";
14 }
15 
16 - (void)didReceiveMemoryWarning
17 {
18     [super didReceiveMemoryWarning];
19     // Dispose of any resources that can be recreated.
20 }
21 
22 - (IBAction)changeScreenButtonClick:(UIButton *)sender
23 {
24     BViewController *b = [[BViewController alloc]init];
25     b.receiveValue = send;
26     UIWindow *window = [UIApplication sharedApplication].delegate.window;
27     window.rootViewController = b;
28 }
29 @end
A.m
1 #import <UIKit/UIKit.h>
2 
3 @interface BViewController : UIViewController
4 @property(nonatomic,copy) NSString *receiveValue;//接收A界面傳過來的值
5 @end
B.h
 1 #import "BViewController.h"
 2 
 3 @interface BViewController ()
 4 
 5 @end
 6 
 7 @implementation BViewController
 8 
 9 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
10 {
11     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
12     if (self) {
13         // Custom initialization
14     }
15     return self;
16 }
17 
18 - (void)viewDidLoad
19 {
20     [super viewDidLoad];
21     // Do any additional setup after loading the view from its nib.
22     NSLog(@"從A界面傳過來的值為:%@",self.receiveValue);
23 }
24 
25 - (void)didReceiveMemoryWarning
26 {
27     [super didReceiveMemoryWarning];
28     // Dispose of any resources that can be recreated.
29 }
30 
31 @end
B.m

 

代理傳值:

代理傳值對應初學者來說有一點難度,但是多使用幾次就好了,像在系統中我們代理這種設計使用的非常廣泛,在此主要說明使用代理傳值的方法。我們在頁面跳轉的過程中,將借助於導航,使用push從A界面跳轉到B界面,使用pop從B界面返回到A界面。

現在我們假設一種場景,我們需要從界面A傳值到界面B,同時也要從界面B傳值到界面A,如何使用代理來實現呢?

首先使用代理傳值,我們需要知道怎么自定義代理,首先先普及一下代理的相關知識。

假如我們需要在A界面傳值到B界面,我們需要在A界面中定義一些協議方法,只需要聲明方法即可,不需要實現,如果其他類想要訪問這些協議方法,只需要遵守這些協議即可。在A中定義的協議方法,相當於一個接口,你想使用A的接口,就要遵守A的協議方法,例如在B中,想要訪問A的協議方法,B就要遵守A的協議。傳值的話,B從A的協議方法中就能獲取到A界面中的值。

如何自己寫一個協議,下面是基本的格式:

 1 @protocol 協議名稱 <NSObject> 2 //協議方法 3 @end 

假設我們現在要在A界面中寫一個協議,具體代碼如下(傳值是從界面A傳到界面B):

 

 1 #import <UIKit/UIKit.h>
 2  
 3 //協議
 4 @protocol aScreenDelegate <NSObject>
 5 -(void)sendValueFromScreenaTOScreenb:(NSString *)value;
 6 @end
 7 
 8 @interface ViewController : UIViewController
 9 @property(nonatomic,assign)id<aScreenDelegate>delegate;
10 - (IBAction)changeScreenButtonClick:(UIButton *)sender;
11 @end
A.h
 1 #import "ViewController.h"
 2 #import "BViewController.h"
 3 @interface ViewController ()
 4 
 5 @end
 6 
 7 @implementation ViewController
 8 
 9 - (void)viewDidLoad
10 {
11     [super viewDidLoad];
12     // Do any additional setup after loading the view, typically from a nib.
13 }
14 
15 - (void)didReceiveMemoryWarning
16 {
17     [super didReceiveMemoryWarning];
18     // Dispose of any resources that can be recreated.
19 }
20 
21 - (IBAction)changeScreenButtonClick:(UIButton *)sender
22 {
23     BViewController *b = [[BViewController alloc]init];
24     NSString *send = @"wyg";
25     self.delegate = b;
26     [_delegate sendValueFromScreenaTOScreenb:send];
27     [self.navigationController pushViewController:b animated:YES];
28 }
29 @end
A.m
1 #import <UIKit/UIKit.h>
2 #import "ViewController.h"
3 @interface BViewController : UIViewController<aScreenDelegate>
4 @end
B.h
 1 @implementation BViewController
 2 
 3 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
 4 {
 5     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
 6     if (self) {
 7         // Custom initialization
 8     }
 9     return self;
10 }
11 -(void)sendValueFromScreenaTOScreenb:(NSString *)value
12 {
13     NSLog(@"從A界面傳過來的值:%@",value);
14 }
15 - (void)viewDidLoad
16 {
17     [super viewDidLoad];
18     // Do any additional setup after loading the view from its nib.
19     
20 }
B.m

 假如你向從界面B,pop到界面A,並把界面B的值傳到界面A,這種使用屬性傳值不太方便,使用代理可以解決,從B界面往A傳值,協議方法應該在B中寫明,在A中遵守協議,下面是具體代碼:

1 #import <UIKit/UIKit.h>
2 #import "BViewController.h"
3 @interface ViewController : UIViewController<bScreenDelegate>
4 - (IBAction)changeScreenButtonClick:(UIButton *)sender;
5 @end
A.h
 1 #import "ViewController.h"
 2  
 3 @interface ViewController ()
 4 
 5 @end
 6 
 7 @implementation ViewController
 8 
 9 - (void)viewDidLoad
10 {
11     [super viewDidLoad];
12     // Do any additional setup after loading the view, typically from a nib.
13 }
14 //代理方法
15 -(void)sendValueFromBtoA:(NSString *)str
16 {
17     NSLog(@"從B界面傳過來的值為:%@",str);
18 }
19 - (IBAction)changeScreenButtonClick:(UIButton *)sender
20 {
21     BViewController *b = [[BViewController alloc]init];
22     b.delegate = self;
23     [self.navigationController pushViewController:b animated:YES];
24 }
25 @end
A.m
 1 #import <UIKit/UIKit.h>
 2 
 3 @protocol bScreenDelegate <NSObject>
 4 -(void)sendValueFromBtoA:(NSString *)str;
 5 @end
 6 
 7 @interface BViewController : UIViewController
 8 @property(nonatomic,assign) id<bScreenDelegate>delegate;
 9 - (IBAction)popButtonClick:(UIButton *)sender;
10 @end
B.h
 1 #import "BViewController.h"
 2 
 3 @interface BViewController ()
 4 
 5 @end
 6 
 7 @implementation BViewController
 8 
 9 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
10 {
11     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
12     if (self) {
13         // Custom initialization
14     }
15     return self;
16 }
17 
18 - (void)viewDidLoad
19 {
20     [super viewDidLoad];
21     // Do any additional setup after loading the view from its nib.
22     
23 }
24 - (IBAction)popButtonClick:(UIButton *)sender
25 {
26     NSString *str = @"wxy";
27     [_delegate sendValueFromBtoA:str];
28     [self.navigationController popViewControllerAnimated:YES];
29 }
30 @end
B.m

 

block傳值

使用block傳值,我們需要自定義代理,這種寫法相對來說是比較麻煩的,使用block傳值的話,會使得代碼量大大縮減,現在我們假設我們要把界面A上的值傳到界面B,使用block來實現。

現在假設我們想在界面A上直接獲取界面B上的信息,如何獲取,代碼如下:

1 #import <UIKit/UIKit.h>
2 #import "BViewController.h"
3 @interface ViewController : UIViewController
4 @end
A.h
 1 #import "ViewController.h"
 2 #import "BViewController.h"
 3 @interface ViewController ()
 4 
 5 @end
 6 @implementation ViewController
 7 
 8 - (void)viewDidLoad
 9 {
10     [super viewDidLoad];
11     // Do any additional setup after loading the view, typically from a nib.
12     BViewController *b = [[BViewController alloc]init];
13     [b converyValueToA:^(NSString *str) {
14         NSLog(@"B界面上的值為:%@",str);
15     }];
16 }
17 @end
A.m
1 #import <UIKit/UIKit.h>
2 @interface BViewController : UIViewController
3 -(void)converyValueToA:(void(^)(NSString *))block;
4 @end
B.h
 1 #import "BViewController.h"
 2 
 3 @interface BViewController ()
 4 
 5 @end
 6 
 7 @implementation BViewController
 8 
 9 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
10 {
11     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
12     if (self) {
13         // Custom initialization
14     }
15     return self;
16 }
17 -(void)converyValueToA:(void (^)(NSString *))block
18 {
19     NSString *name = @"wxy";
20     block(name);
21 }
22 - (void)viewDidLoad
23 {
24     [super viewDidLoad];
25     // Do any additional setup after loading the view from its nib.
26     
27 }
28 
29 @end
B.m

 

通知傳值

通知傳值有點類似於廣播,有發送者,有監聽者,比如A想接受B的值,B要發送一個通知,A只要監聽這個通知,就能接收到值,通知傳值就不細述。

例如發送一個通知:

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:通知名字 object:self userInfo:傳遞參數];

接收一個通知:

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

[center addObserver:self selector:@selector(receiveNofitication:) name:通知名字 object:nil];

-(void)receiveNofitication:(NSNotification *)notification
{//接收到通知,執行相關代碼}

 

跨應用傳值

 

     跨頁面跳轉,顧名思義就是在一個應用內不同界面之間的跳轉,如果我們想要從一個應用程序跳轉到另一個應用程序怎么辦,加入你的手機上同時安裝了淘寶和支付寶兩個應用程序,你點擊支付的時候,手機會自動打開手機上安裝的應用支付寶,這個功能如何實現。
     想要跨應用跳轉,我們首先要確保手機上安裝了這兩個應用,或者模擬器上安裝了這兩個應用,然后點擊控件觸發事件實現不同應用之間的跳轉。
     我們先要分析一下如何實現這個功能:
     如果我們從一個應用跳轉到另一個應用,我們需要有另一個應用的標示,我們應該稱之為URL,點擊響應事件,跳轉到另一個應用即可。
 
     如何給應用設置URL:TAGGET->Info->URL Types->URL Schemes
     在里面輸入標示即可。
    
     現在假設我在模擬器上安裝了兩個應用,一個叫BuyApp,設置標示為buy,一個叫PayApp,設置標示為pay.(下圖為BuyApp界面)
 
 
 
現在我需要點擊按鈕,跳轉到支付界面。(並且在跳轉的時候傳遞兩個參數)
現在我們已經知道支付界面的URL是pay.
我們可以在按鈕點擊事件中寫入下面的代碼即可:
 1 - (IBAction)toPayApp:(id)sender
 2 {
 3     //設置跳轉到應用程序的鏈接
 4     //雙斜杠之后是傳遞的參數,多個參數使用&連接
 5     NSURL *url = [NSURL URLWithString:@"payApp://name=iPhone6&price=5288"];
 6     //跳轉前先判斷,是否可以打開鏈接
 7     if ([[UIApplication sharedApplication] canOpenURL:url] == YES)
 8     {
 9         [[UIApplication sharedApplication] openURL:url];
10     }
11     else
12     {
13         NSLog(@"連接不能打開,應用程序未安裝");
14     }
15 }
應用跳轉

現在我們已經進入到PayApp,如何在這個應用中接受傳過來的參數呢?

我們可以在AppDelegate這個.m文件中添加下面的方法:

 1 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 

 當前應用程序被別的應用程序喚醒時,執行此方法。
參數分別是:
URL:程序跳轉的連接地址
sourceApplication:從哪個應用程序跳轉過來。
我們可以從程序跳轉的連接地址中提取出傳遞過來的參數。這樣在第二個應用中能夠獲取到第一個應用傳遞過來的參數。
如果我們在PayApp界面執行完畢后,返回到原程序,執行方法與上面的步驟相同。
 
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM