zoukankan      html  css  js  c++  java
  • 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界面执行完毕后,返回到原程序,执行方法与上面的步骤相同。
     
     
     
     
     
     
  • 相关阅读:
    植物:柏树
    植物:水杉
    植物:珙桐
    植物:桫椤
    汉语-成语:悠闲自在
    植物:孑遗植物
    汉语-词语:孑遗
    汉语-词语:调味品
    调味品:酱油
    netstat 命令详解
  • 原文地址:https://www.cnblogs.com/wangyaoguo/p/4874452.html
Copyright © 2011-2022 走看看