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中有幾種傳參方式嗎?沒想到其他問題回答的很好,唯獨這個問題一知半解,勉強回