一篇文章学会页面传值的10种方法(上)
---恢复内容开始---
##1、最简单AB面正向传值 ###效果如下: ![最简单的正向传值.gif](//upload-images.jianshu.io/upload_images/3067941-0190f09d6f86dae7.gif?imageMogr2/auto-orient/strip) 首先我们先创建两个视图控制器ViewController.swift和SubViewController.swift设置第一个界面
首先在第一个界面创建好一个TextFeild,用来写我们要传的文字
import UIKit
class ViewController: UIViewController {
let textField = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor()
textField.frame = CGRectMake(7, 100, 400, 50)
textField.borderStyle = .RoundedRect
self.view.addSubview(textField)
}
}
在这里我们设置当点击屏幕跳转到第二个界面
并且执行传值操作
在SubViewController里设置一个公开的属性去接收数据
var string: String?
在ViewController里设置点击屏幕时传值
//当点击屏幕时执行该方法
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//MARK:创建第二个界面的对象
let svc = SubViewController()
//MARK:通过属性来进行正向传值
svc.string = self.textField.text
//跳转到第二个界面
self.presentViewController(svc, animated: true, completion: nil)
}
在第二个界面里创建好一个label用来接收值
添加一个label控件
//控件不公开
private let textLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.cyanColor()
textLabel.frame = CGRectMake(7, 200, 400, 50)
textLabel.textAlignment = .Center
self.view.addSubview(textLabel)
在视图将要显示的时候将传进来的值赋值给控件
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//在视图将要显示的时候,去将传进来的值,赋给控件
self.textLabel.text = string
}
当点击屏幕时,返回第一个界面
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//返回上一页面
self.dismissViewControllerAnimated(true, completion: nil)
}
2、利用属性进行AB页面的反向传值
效果如下:
首先我们先创建两个视图控制器ViewController.swift和SubViewController.swift
第一步
在ViewController里面设置好一个固定的Label,设置显示的文字为:Location Services,和一个显示状态的statusLabel
第二步
在SubViewController里定义一个属性,去接收返回值的目标对象
var vc: ViewController?
然后放置一个UISwitch,设置开关的相应方法
//设置开关的响应方法
func swAction(sw:UISwitch){
//判断状态
if sw.on {
//MARK:此步骤实现反向传值,将状态值回传给A页面
self.vc?.lsStatusLabel.text = "ON"
}else{
self.vc?.lsStatusLabel.text = "OFF"
}
}
第三步
在ViewController里面设置touchBegan方法
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//MARK:实例化一个第二个界面的对象
let svc = SubViewController()
//给B页面传值,告诉B回传数据的目标是谁
svc.vc = self
//点击屏幕时跳转到第二个界面
self.presentViewController(svc, animated: true, completion: nil)
}
3、利用NSUserDefult双向传值
效果如下:
原理:NSUserDefaults是系统对plist文件封装好的一个类,我们可以通过这个类对文件进行读写,在在*HomeDirectory/Library/preferences/XXX.userdefaults.plist
*下。利用NSUserDefaults的特性,将某一个界面要传出的值存入到plist文件中,然后再另一个界面从plist文件读出来,就完成了传值操作
第一步
创建好ViewController和SubViewController
在ViewController中布局好Label的位置
第二步
在SubViewController中创建好5个按钮,为每个按钮添加tag值,并且实现交替选中效果,代码如下:
for i in 0..<5 {
let button = UIButton(type: .System)
button.setTitle("第\(i + 1)个按钮", forState: .Normal)
button.frame = CGRectMake(7, CGFloat(150 + i * 100), 400, 100)
//为每一个button设置tag值
button.tag = 100 + i
//点击事件
button.addTarget(self, action: #selector(self.buttonAction(_:)), forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
设置点击事件,实现交替选中效果
for i in 0..<5 {
let btn = self.view.viewWithTag(100 + i) as! UIButton
btn.selected = false
}
sender.selected = true
在点击事件中同时使用NSUserDefaults将该按钮的tag值写入plist文件,做成数据记录
首先获取NSUserDefaults对象,这个对象是一个单例对象
let userDefaults = NSUserDefaults.standardUserDefaults()
将按钮的tag值做成数据记录
let selectedIndex = String(sender.tag)
写入plist文件
userDefaults.setObject(selectedIndex, forKey: "selectedIndex")
回写文件
userDefaults.synchronize()
第三步
从ViewController的viewWillAppear函数中我们读取plist文件,并完成反向传值
首先获取NSUserDefaults的对象
let userDefaults = NSUserDefaults.standardUserDefaults()
读取出数据,获取出SubViewController中对应button的tag值
let si = userDefaults.objectForKey("selectedIndex")
此时的si是AnyObject类型,我们将他转化成int类型
let tag = si?.intValue
然后修改ViewController中的label的文字
self.label.text = "第\(tag! - 99)个按钮是选中转态"
到这儿,就完成了反向传值的过程,第二个界面的哪个button被选中在第一个界面就会显示出来,效果如下
但是,再次从第一个界面跳回第二个界面是,按钮就变成全部为未选中状态,下面就是实现执行正向传值
同样是获取NSUserDefaults对象,然后读取数据,最后获取tag值找到对象button,设置该button为选中状态,在这儿还需读者自行去完成接下来的内容
4、使用系统闭包反向传值
这种方式是使用系统自带的闭包
self.presentViewController(UIViewController, animated: Bool) {
code
}
这种传值方式传值会有延迟,因为是在执行完页面切换后再去进行传值
效果如下:
第一步
首先创建好ViewController和SubViewController
viewController中布局好一个label用来显示接收到数据,在SubViewController中布局好一个TextFeild用来写数据
第二步
在SubViewController中创建一个接收属性
var vc: ViewController?
第三步
在ViewController中写touchBegan方法
获取第SubViewController对象,在presentViewController方法中打开闭包,在将ViewController传给SubViewController的vc
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let svc = SubViewController()
//将视图控制器本身传过去,方便回传使用
self.presentViewController(svc, animated: true) {
//这个方法是在弹出下一页面后执行
svc.vc = self
}
}
第四步
在SubViewController中写touchBegan方法
在self.dismissViewControllerAnimated方法中打开闭包将属性tf中的文字回传给属性vc的textLabel
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.dismissViewControllerAnimated(true) {
//利用这个闭包来回传数据
self.vc!.textLabel.text = self.tf.text
}
}
5、自定义闭包传值
和使用系统闭包传值的思想相同,自定义闭包传值就是自己声明一个闭包,通过这个闭包来进行页面之间的相互传值
效果同第4种
第一步
创建好ViewController和SubViewController
分别在vc和subvc中布局好一个label和textFeild
在SubViewController中声明一个闭包
var backValueClusore:((text:String)->Void)?
第二步
在ViewController中写touchBegan方法
获取第SubViewController对象,在presentViewController方法中打开闭包,在将ViewController传给SubViewController的vc
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let svc = SubViewController()
self.presentViewController(svc, animated: true, completion: nil)
//MARK:将闭包中的text赋值给self.textLabel
svc.backValueclusore = {(text:String)->Void in
self.textLabel.text = text
}
第三步
在SubViewController中写touchBegan方法
在self.dismissViewControllerAnimated方法中打开闭包将属性tf中的文字回传给属性vc的textLabel
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//MARK:直接执行闭包
self.dismissViewControllerAnimated(true, completion: nil)
self.backValueclusore!(text:self.tf.text!)
---恢复内容结束---
##1、最简单AB面正向传值效果如下:
首先我们先创建两个视图控制器ViewController.swift和SubViewController.swift
设置第一个界面
首先在第一个界面创建好一个TextFeild,用来写我们要传的文字
import UIKit
class ViewController: UIViewController {
let textField = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor()
textField.frame = CGRectMake(7, 100, 400, 50)
textField.borderStyle = .RoundedRect
self.view.addSubview(textField)
}
}
在这里我们设置当点击屏幕跳转到第二个界面
并且执行传值操作
在SubViewController里设置一个公开的属性去接收数据
var string: String?
在ViewController里设置点击屏幕时传值
//当点击屏幕时执行该方法
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//MARK:创建第二个界面的对象
let svc = SubViewController()
//MARK:通过属性来进行正向传值
svc.string = self.textField.text
//跳转到第二个界面
self.presentViewController(svc, animated: true, completion: nil)
}
在第二个界面里创建好一个label用来接收值
添加一个label控件
//控件不公开
private let textLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.cyanColor()
textLabel.frame = CGRectMake(7, 200, 400, 50)
textLabel.textAlignment = .Center
self.view.addSubview(textLabel)
在视图将要显示的时候将传进来的值赋值给控件
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//在视图将要显示的时候,去将传进来的值,赋给控件
self.textLabel.text = string
}
当点击屏幕时,返回第一个界面
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//返回上一页面
self.dismissViewControllerAnimated(true, completion: nil)
}
2、利用属性进行AB页面的反向传值
效果如下:
首先我们先创建两个视图控制器ViewController.swift和SubViewController.swift
第一步
在ViewController里面设置好一个固定的Label,设置显示的文字为:Location Services,和一个显示状态的statusLabel
第二步
在SubViewController里定义一个属性,去接收返回值的目标对象
var vc: ViewController?
然后放置一个UISwitch,设置开关的相应方法
//设置开关的响应方法
func swAction(sw:UISwitch){
//判断状态
if sw.on {
//MARK:此步骤实现反向传值,将状态值回传给A页面
self.vc?.lsStatusLabel.text = "ON"
}else{
self.vc?.lsStatusLabel.text = "OFF"
}
}
第三步
在ViewController里面设置touchBegan方法
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//MARK:实例化一个第二个界面的对象
let svc = SubViewController()
//给B页面传值,告诉B回传数据的目标是谁
svc.vc = self
//点击屏幕时跳转到第二个界面
self.presentViewController(svc, animated: true, completion: nil)
}
3、利用NSUserDefult双向传值
效果如下:
原理:NSUserDefaults是系统对plist文件封装好的一个类,我们可以通过这个类对文件进行读写,在在*HomeDirectory/Library/preferences/XXX.userdefaults.plist
*下。利用NSUserDefaults的特性,将某一个界面要传出的值存入到plist文件中,然后再另一个界面从plist文件读出来,就完成了传值操作
第一步
创建好ViewController和SubViewController
在ViewController中布局好Label的位置
第二步
在SubViewController中创建好5个按钮,为每个按钮添加tag值,并且实现交替选中效果,代码如下:
for i in 0..<5 {
let button = UIButton(type: .System)
button.setTitle("第\(i + 1)个按钮", forState: .Normal)
button.frame = CGRectMake(7, CGFloat(150 + i * 100), 400, 100)
//为每一个button设置tag值
button.tag = 100 + i
//点击事件
button.addTarget(self, action: #selector(self.buttonAction(_:)), forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
设置点击事件,实现交替选中效果
for i in 0..<5 {
let btn = self.view.viewWithTag(100 + i) as! UIButton
btn.selected = false
}
sender.selected = true
在点击事件中同时使用NSUserDefaults将该按钮的tag值写入plist文件,做成数据记录
首先获取NSUserDefaults对象,这个对象是一个单例对象
let userDefaults = NSUserDefaults.standardUserDefaults()
将按钮的tag值做成数据记录
let selectedIndex = String(sender.tag)
写入plist文件
userDefaults.setObject(selectedIndex, forKey: "selectedIndex")
回写文件
userDefaults.synchronize()
第三步
从ViewController的viewWillAppear函数中我们读取plist文件,并完成反向传值
首先获取NSUserDefaults的对象
let userDefaults = NSUserDefaults.standardUserDefaults()
读取出数据,获取出SubViewController中对应button的tag值
let si = userDefaults.objectForKey("selectedIndex")
此时的si是AnyObject类型,我们将他转化成int类型
let tag = si?.intValue
然后修改ViewController中的label的文字
self.label.text = "第\(tag! - 99)个按钮是选中转态"
到这儿,就完成了反向传值的过程,第二个界面的哪个button被选中在第一个界面就会显示出来,效果如下
但是,再次从第一个界面跳回第二个界面是,按钮就变成全部为未选中状态,下面就是实现执行正向传值
同样是获取NSUserDefaults对象,然后读取数据,最后获取tag值找到对象button,设置该button为选中状态,在这儿还需读者自行去完成接下来的内容
4、使用系统闭包反向传值
这种方式是使用系统自带的闭包
self.presentViewController(UIViewController, animated: Bool) {
code
}
这种传值方式传值会有延迟,因为是在执行完页面切换后再去进行传值
效果如下:
第一步
首先创建好ViewController和SubViewController
viewController中布局好一个label用来显示接收到数据,在SubViewController中布局好一个TextFeild用来写数据
第二步
在SubViewController中创建一个接收属性
var vc: ViewController?
第三步
在ViewController中写touchBegan方法
获取第SubViewController对象,在presentViewController方法中打开闭包,在将ViewController传给SubViewController的vc
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let svc = SubViewController()
//将视图控制器本身传过去,方便回传使用
self.presentViewController(svc, animated: true) {
//这个方法是在弹出下一页面后执行
svc.vc = self
}
}
第四步
在SubViewController中写touchBegan方法
在self.dismissViewControllerAnimated方法中打开闭包将属性tf中的文字回传给属性vc的textLabel
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.dismissViewControllerAnimated(true) {
//利用这个闭包来回传数据
self.vc!.textLabel.text = self.tf.text
}
}
5、自定义闭包传值
和使用系统闭包传值的思想相同,自定义闭包传值就是自己声明一个闭包,通过这个闭包来进行页面之间的相互传值
效果同第4种
第一步
创建好ViewController和SubViewController
分别在vc和subvc中布局好一个label和textFeild
在SubViewController中声明一个闭包
var backValueClusore:((text:String)->Void)?
第二步
在ViewController中写touchBegan方法
获取第SubViewController对象,在presentViewController方法中打开闭包,在将ViewController传给SubViewController的vc
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let svc = SubViewController()
self.presentViewController(svc, animated: true, completion: nil)
//MARK:将闭包中的text赋值给self.textLabel
svc.backValueclusore = {(text:String)->Void in
self.textLabel.text = text
}
第三步
在SubViewController中写touchBegan方法
在self.dismissViewControllerAnimated方法中打开闭包将属性tf中的文字回传给属性vc的textLabel
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//MARK:直接执行闭包
self.dismissViewControllerAnimated(true, completion: nil)
self.backValueclusore!(text:self.tf.text!)