1. 程式人生 > >iOS頁面間幾種傳值方式

iOS頁面間幾種傳值方式

傳值方法

  • 屬性
  • 方法
  • 代理
  • block
  • 通知
  • 單例
    頁面間傳值有八大傳值方式,下面我就簡單介紹下頁面間常用的傳值方式,但對於每種方式的詳細介紹由於內容很多,我會把每種方式單獨列出作為一篇文章詳細介紹,本文不做詳細說明

屬性傳值

第二個介面(DetailViewController)中的label顯示第一個介面(RootViewController)textField中的文字
首先我們建立一個RootViewController和一個DetailViewController,在DetailViewController中宣告一個textString屬性,用於接收傳過來的字串。

#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController @property(nonatomic,copy) NSString *textString://屬性傳值 @end

同時建立一個Label用來顯示傳過的字串

#import "DetailViewController.h"

@interface DetailViewController()

@end

@implementation DetailViewController 

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel
*label = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 50, 44)]; label.backgroundColor = [UIColor grayColor]; label.font = [UIFont systemFontOfSize:20]; label.numberOfLines = 0; label.text = self.textString;//屬性傳值得到顯示文字 [self.view addSubview:labelOne]; }

在RootViewController.m檔案中引入DetailViewController同時宣告一個textField屬性用來輸入字串

#import "RootViewController.h"
#import "DetailViewController.h"

@interface RootViewController ()
@property(nonatomic,strong) UITextField *textField;
@end

@implementataion RootViewController
//懶載入,重寫textField的getter方法
- (UITextField *)textField {
    if (!_textField) {
        _textField = [[UITextField alloc]initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.bounds) - 50, 44)];
    }
    return _textField;
}

然後在RootViewController上我們建立並新增一個button,當點選button時響應相應方法進行檢視間的切換並且完成檢視間的傳值

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.textField];

    UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeCustom];
    pushButton.bounds = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds) - 50, 44);
    pushButton.center = self.view.center;
    [pushButton setTitle:@"點選進入DetailVC" forState:UIControlStateNormal];
    [pushButton addTarget:self action:@selector(respondsToPushButton:) forControlEvents:UIControlStateNormal];    
}

//pushbutton點選事件
- (void)respondsToPushButton:(UIButton *)sender {
    DetailViewController *detailVc = [[DetailViewController alloc]init];
    detailVc.textString = self.textField.text;
    [self.navigationController pushViewController:detailVc animated:YES];
}

方法傳值

需求同一中的屬性傳值 一樣,但是要通過使用方法傳值,可以直接將方法與初始化方法合併,此時當觸發RootViewController的按鈕點選事件並跳轉到DetailViewController時,在按鈕點選事件中可以直接通過DetailViewController的初始化,將值傳入firstValue中:

初始化方法如下:
首先DetailViewController檢視中需要有一個Label用來儲存傳遞過來的值:

//重寫初始化方法,用於傳值。可以自定義初始化方法,也可以重寫系統初始化方法
- (instancetype)initWithFrame:(CGRect)frame String:(NSString *)str
{
    self = [super initWithFrame:frame];
    if (self) {
        _label.text = str; 
    }
    return self;
}

方法傳值:

//pushbutton點選事件
- (void)respondsToPushButton:(UIButton *)sender {
    DetailViewController *detailVc = [[DetailViewController alloc]initWithFrame:self.view.bounds String:self.textField.text];

    [self.navigationController pushViewController:detailVc animated:YES];
}
//這樣就可以直接通過初始化方法獲得傳遞過來的值:

代理傳值

RootViewController頁面push到DetailViewControllers頁面,如果DetailViewController頁面的資訊想回傳(回撥)到RootViewController頁面,用代理傳值,其中DetailViewController定義協議和宣告代理,RootViewController確認並實現代理,RootViewController作為DetailViewController的代理

首先在DetailViewController.h檔案中我們建立協議方法

#import <UIKit/UIKit.h>

@class DetailViewController;
//DetailViewController是協議方,RootViewController是代理方
@protocol DetailViewControllerDelegate <NSObject>

- (void)detailViewController:(DetailViewController *)Vc didClickedButtonWithColor:(UIColor *)color;

@end

@interface DetailViewController : UIViewController
//代理屬性
@property(nonatomic,assign) id<DetailViewControllerDelegate> delegate;

@end

在DetailViewController的.m中我們新增一個pop返回RootViewControlelr的button,併為其新增響應事件

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor redColor];
    [self.view addSubview:self.textField];

    UIButton *popButton = [UIButton buttonWithType:UIButtonTypeCustom];
    popButton.bounds = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds) - 50, 44);
    popButton.center = self.view.center;
    [popButton setTitle:@"點選返回RootVc" forState:UIControlStateNormal];
    [popButton addTarget:self action:@selector(respondsToPopButton:) forControlEvents:UIControlStateNormal];    
}

//popbutton點選事件
- (void)respondsToPopButton:(UIButton *)sender {
    if (self.delegate && [self.delegate respondsToSelector:@selector(detailViewController:didClickedButtonWithColor:)]) {
        [self.delegate detailViewController:self didClickedButtonWithColor:self.view.backgroundColor];
    }
    [self.navigationController popViewControllerAnimated:YES];
}

RootViewController的.m檔案中我們指定代理並讓其執行代理的方法
然後在RootViewController上我們寫在push到DetailViewController的方法中

//pushbutton點選事件
- (void)respondsToPushButton:(UIButton *)sender {
    DetailViewController *detailVc = [[DetailViewController alloc]init];
    //為detailVc指定代理物件
    detailVc.delegate = self;
    detailVc.textString = self.textField.text;
    [self.navigationController pushViewController:detailVc animated:YES];
}

//實現代理方法
- (void)detailViewController:(DetailViewController *)Vc didClickedButtonWithColor:(UIColor *)color
{
    //使用傳來的color設定當前控制器檢視的背景色
    self.view.backgroundColor = color;
}

block傳值

block傳值也是從第二個介面(DetailViewController)傳給第一個介面(RootViewController),和代理傳值方法類似

首先我們在DetailViewcontroller的.h檔案中,定義block屬性

#import <UIKit/UIKit.h>

//第一步,定義block型別
typedef void(^ColorBlock)(UIColor *);

@interface DetailViewController : UIViewController

//第二步,定義block屬性
@property(nonatomic,copy) ColorBlock colorBlock;

@end

再在DetailViewcontroller的.m檔案中執行block

//popbutton點選事件
- (void)respondsToPopButton:(UIButton *)sender {
    if (_colorBlock) {
        _colorBlock(self.view.backgroundColor);
    }
    [self.navigationController popViewControllerAnimated:YES];
}

在RootViewController的.m檔案中,其他不變,在pushbutton的響應方法裡我們為block屬性賦值完成block傳值

//pushbutton點選事件
- (void)respondsToPushButton:(UIButton *)sender {
    DetailViewController *detailVc = [[DetailViewController alloc]init];
    //在這裡拿到對應控制器的block屬性,實現並獲得傳遞的引數
    detail.colorBlock = ^(UIColor *color){
        self.view.backgroundColor = color;
    };
    [self.navigationController pushViewController:detailVc animated:YES];
}

通知傳值

要使用通知傳值先要了解其基本概念
NSNotification這個類可以理解為一個訊息物件,其中有三個成員變數。
這個成員變數是這個訊息物件的唯一標識,用於辨別訊息物件。

@property (readonly, copy) NSString *name;

這個成員變數定義一個物件,可以理解為針對某一個物件的訊息。

@property (readonly, retain) id object;

這個成員變數是一個字典,可以用其來進行傳值。

@property (readonly, copy) NSDictionary *userInfo;

NSNotification的初始化方法:

- (instancetype)initWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;

+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject;

+ (instancetype)notificationWithName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

注意:官方文件有明確的說明,不可以使用init進行初始化

NSNotificationCenter這個類是一個通知中心,使用單例設計,每個應用程式都會有一個預設的通知中心。用於排程通知的傳送的接受。

新增一個觀察者,可以為它指定一個方法,名字和物件。接受到通知時,執行方法。

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;

傳送通知訊息的方法

- (void)postNotification:(NSNotification *)notification;
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

移除觀察者的方法

- (void)removeObserver:(id)observer;
- (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;

幾點注意:
1、如果傳送的通知指定了object物件,那麼觀察者接收的通知設定的object物件與其一樣,才會接收到通知,但是接收通知如果將這個引數設定為了nil,則會接收一切通知。
2、觀察者的SEL函式指標可以有一個引數,引數就是傳送的死奧西物件本身,可以通過這個引數取到訊息物件的userInfo,實現傳值。

通知不需要再頁面跳轉時設定代理屬性或者block屬性,只需要在要接收資訊的地方註冊通知,在傳值的地方傳送通知即可,但切記註冊通知一定要在傳送通知的程式碼執行之前,具體實現方法
首先,我們在需要接收通知的地方註冊觀察者,比如:

//獲取通知中心單例物件
NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
//添加當前類物件為一個觀察者,name和object設定為nil,表示接收一切通知
[center addObserver:self selector:@selector(notice:) name:@"123" object:nil];

我們可以在回撥的函式中取到userInfo內容,如下:

-(void)notice:(id)sender{
    NSLog(@"%@",sender);
}

之後,在我們需要時傳送通知訊息

//建立一個訊息物件
NSNotification * notice = [NSNotification notificationWithName:@"123" object:nil userInfo:@{@"1":@"123"}];
//傳送訊息
[[NSNotificationCenter defaultCenter]postNotification:notice];

單例傳值

單例的建立方法有很多,還有一些單例的具體建立方法請瀏覽我的關於單例的部落格,我麼這裡先建立一個簡單單例作為例子,開發中常用的建立簡單單例方法如下:
建立一個單例類ControllerManager
首先在ControllerManager的.h檔案中宣告一個方法

#import <Foundation/Foundation.h>

@interface ControllerManager : NSObject

@property(nonatomic,copy) NSString *str;
+ (ControllerManager *)shareManager;

@end

在ControllerManager的.m檔案中實現

#import "ControllerManager"
//先初始化一個靜態變數
static ControllerManager *manager = nil;

@implementation ControllerManager

+ (ControllerManager *)shareManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
        manager = [[ControllerManager alloc]init];
    });
    return manager;
}

@end

這樣在程式其他任何地方都可以通過呼叫單例方法進行賦值和傳值,例如在RootViewController中賦值

#import "RootViewController.h"
#import "ControllerManager.h"

@interface RootViewController()

@end

@implementation RootViewController

- (void)viewDidLoad {
    //單例傳值 將要傳遞的資訊存入單例中
    [ControllerManager shareManager].str = @"Hello World";
    //等價於
    [[ControllerManager shareManager]setStr:@"Hello World"];
}

@end

在DetailViewController中取值

#import "DetailViewController"

@interface DetailViewController()

@end

@implementation DetailViewController

- (void)viewDidLoad {
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 150, 30)];
    label.text = [ControllerManager shareManager].str;
    [self.view addSubview:label];
}

@end

相關推薦

iOS頁面方式

傳值方法 屬性 方法 代理 block 通知 單例 頁面間傳值有八大傳值方式,下面我就簡單介紹下頁面間常用的傳值方式,但對於每種方式的詳細介紹由於內容很多,我會把每種方式單獨列出作為一篇文章詳細介紹,本文不做詳細說明 屬性傳值 第二個介面(Det

Struts2頁面到action的方式

struts2中的Action接收表單傳遞過來的引數有幾種方法: 傳統的做法如,登陸表單login.jsp: <form action="login" method="post" name=

GridViewControl頁面方法

GridViewControl 單選框選中行頁面之間傳值 1. 第一種用構造方法傳值 FormGetDuty frm = new FormGetDuty (strdebugPeople, strCRAFTPLANID, "質檢推送按鈕"); f

ios常用的三方式

總結我專案中常用的三種傳值方式 近期在研究Python,公司正好有Python專案,對於自己來說也算是橫向發展 1:Block傳值 場景:比如在同一個頁面(A)點選了型別,彈出新的頁面(B),這時候需要獲取新頁面點選的是哪個型別值,,所以就需要新頁

Jsp頁面方式

1.JavaScript傳參:這種傳參方式用opener關鍵字, 可以實現跨頁傳參.其用法就是用opener關鍵字呼叫父窗體的一個元件.  舉例:   opener.myform.txt.value = document.myform.txt.value;  優點:   簡單,對網路傳輸限制比較底.  缺點:

C# 子窗體與父窗體之間方式

做了很多專案,很多專案都用到子父窗體之間的傳值。。 父窗體傳入子窗體都比較簡單,而子窗體傳入父窗體因為有很多不通道的需求,所以·搞起來有點頭大。 先說父窗體傳入子窗體: 將父窗體控制元件上的值傳入子窗體的控制元件上: Form1為父窗體 Form2為子窗體 Form1 單

iOS類與類之間的三方式

一代理方式 什麼是代理模式 傳入的物件,代替當前類完成了某一個功能,稱為代理模式. 實現代理有以下方法 在要傳值的類中 1> 宣告代理方法 2> 定義代理屬性 3> 在適當的時候呼叫代理方法 在要接受值的類中 1&g

Struts2頁面到action的三方式

private String username;  private String password;    public String getUsername() {   return username;  }  public void setUsername(String username) {   thi

iOS方式

iOS 有五種傳值方式 一.屬性傳值 屬性傳值最為簡單,但是比較單一,只能從一個檢視傳至另一個檢視, 屬性傳值第一步需要用到什麼型別就定義什麼樣的屬性 新建兩個檢視控制器RootViewController和SecondViewController,從一個頁面傳至第二個頁面

Makefile中的方式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

JS有哪方式?

這裡是修真院前端小課堂,每篇分享文從 【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】 八個方面深度解析前端知識/技能,本篇分享的是: 【JS有哪幾種傳參方式?】 (1)背景介紹: js中的傳值方式,對於簡單型別(比如字串和

Activity之間的三方式

*************************************** 第一種:Extras:額外的,附加的.在Intent中附加額外的訊息 //傳值 Intent intent = new Intent(this, XXXActivity.class); intent.pu

Vue問題的分析

在學習vue過程中自己總結了幾種元件間傳值的方式 1、路由傳參 步驟: ①定義路由時加上引數props: true,在定義路由路徑時要留有引數佔位符: name『用法: to=”’路徑/’+value”』 ②在跳轉到的頁面加上引數props

vue路由query和params的方式

在專案中需要路由傳參,查看了官方文件以及參考了網上其他資料,現總結如下: 一/ params傳參 佔位符:id //宣告式 <router-link :to=`/home/${name}`> //程式設計式 skipMethod (name) {

Struts2的三方式

1.普通的傳值方式 UserActionForCommonParam類 Action類接收三個引數,分別是id,username,content. package com.struts.action; public class UserActionForCommonPar

JS有哪方式

js有哪幾種傳參方式?小課堂【深圳-web-A組】目錄1.背景介紹2.知識剖析3.常見問題4.解決方案5.編碼實戰6.擴充套件思考7.參考文獻8.更多討論1.背景介紹我們今天講的傳參是指頁面之間的資料傳遞。傳統的前端開發中,頁面之間是少有引數互動的,甚至沒有,而在如今的前端環

struts2的三方式之1屬性

屬性傳值也就是普通的傳值方法 先總的說一下屬性傳值是什麼樣子的! 在jsp頁面直接寫就可以了,沒有什麼特殊的要求和servlet的jsp頁面一樣 在Action頁面定義要傳的值,建立get和set方法。可以直接用。 具體參見程式碼,我用myeclipse寫的 .jsp &

vue.js路由的方式及特點,包括router-link,$router.push,動態路由匹配,params和query

最近vue用的比較多,就想對各種知識做一個小結,比如這個就是路由導航的一個小總結。具體內容如下: 一、<router-link> <router-link>標籤中的to屬性用來指定路由路徑。 to的型別:string | Location

Ajax的三方式[ie]

第一種 index.jsp讀取data.xml <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextP

Mybatis的方式,你瞭解嗎?

持續原創輸出,點選上方藍字關注我 目錄 前言單個引數多個引數 使用索引【不推薦】使用@Param使用MapPOJO【推薦】 List傳參陣列傳參總結 前言 前幾天恰好面試一個應屆生,問了一個很簡單的問題:你瞭解過Mybatis中有幾種傳參方式嗎?沒想到其他問題回答的很好,唯獨這個問題一知半解,勉強回