2020-08-19 swift 传值的几个方式

页面传值是指:父子页面之间、非父子页面之间、兄弟页面之间、非兄弟页面之间数据互通的方式,是为页面传值(个人见解)

这里只讲怎么使用,至于每个传值方式是什么意思,什么原理吧啦吧啦的一堆问题,请移步百度找到你想要的答案,谢谢!

这里我所整理的传值方式有六个,分别是:
1、单例传值
2、通知传值
3、属性传值
4、闭包传值(Block)
5、代理传值
6、NSUserDefaults传值

1、单例传值

注:这里就不写怎么创建单例类了,你实在是想要知道只能去百度了,谢谢!

言归正传

传值描述:

A页面、B页面、X单例类
A页面-》B页面-》B页面给X单例类属性赋值-》A页面从X单例类属性获取所传的值

实现代码步骤:

1.先创建一个单例类,声明好所需的属性
2.在B页面调用单例类的属性,并给单例类属性赋值
3.在A页面中使用 viewWillAppear() 生命周期里,使用单例类属性,给UI控件赋值

直接上代码

单例类代码
import UIKit
//MARK:- X单例类 
class HYSingle: NSObject {

    static let sharedInstance = HYSingle()
    private override init() {}
    //声明字符串变量
    var sendValue = ""
    
}
赋值页面 - B页面
import UIKit
//MARK:- B页面 

class ADLViewController: UIViewController {
  //传值的输入框
    var textF = UITextField()
    override func viewDidLoad() {
        super.viewDidLoad()
        //传值的输入框
        textF.frame = CGRect(x: 50, y: 170, width: view.frame.size.width - 100, height: 50)
        textF.attributedPlaceholder = NSAttributedString(string: "请输入要传的值", attributes: [NSAttributedString.Key.foregroundColor : UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.5)])
        textF.borderStyle = .line
        textF.textColor = .white
        textF.backgroundColor = UIColor.init(red: 0.283, green: 0.290, blue: 0.293, alpha: 1)
        view.addSubview(textF)
        //发送传值按钮
        let btn = UIButton()
        btn.frame = CGRect(x: 70, y: (textF.frame.origin.y+textF.frame.size.height)+50, width: view.bounds.width-(70*2), height: 50)
        btn.backgroundColor = .orange
        btn.setTitle("开始传值了", for: .normal)
        btn.addTarget(self, action: #selector(btnAction(btn:)), for: .touchUpInside)
        view.addSubview(btn)
    }
    /******************向A页面传值**************************/
    @objc func btnAction(btn:UIButton){
        //向A页面传值
        //获取输入框内容,并给单例类属性赋值
        HYSingle.sharedInstance.sendValue = textF.text!
        //返回上级页面
        self.navigationController?.popViewController(animated: true)
    }
    /********************************************/
}

获取页面 - A页面

import UIKit
//MARK:- A页面
class HDLViewController: UIViewController {
    
    var labels = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //跳转下级页面
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: 120, height: 50)
        ymBtn_01.setTitle("跳转下级页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //接收传值的标签
        labels.frame = CGRect(x: 50, y: (ymBtn_01.frame.origin.y+ymBtn_01.frame.size.height)+50, width: view.frame.size.width-100, height: 50)
        labels.backgroundColor = .darkGray
        labels.textColor = .white
        view.addSubview(labels)
    }
    /******************接收B页面传来的值**************************/
    //接收B页面传来的值
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        //接收传值,并赋值给标签
        self.labels.text = HYSingle.sharedInstance.sendValue
    }
    /********************************************/
    @objc func tiaozhuanyemianclick(sender:UIButton){
        //声明变量名,并初始化类名
        let aDLVC = ADLViewController.init()
        aDLVC.title = "页面 2"
        aDLVC.view.backgroundColor = UIColor.init(named: "bgColor")
        //跳转下级页面
        navigationController?.pushViewController(aDLVC, animated: true)
        
    }
}


----------------------------------分割线---------------------------------------


2. 通知传值

传值描述:

A页面、B页面
A页面-》B页面-》B页面使用通知(NotificationCenter)传值-》A页面使用通知(NotificationCenter)获取传值

实现代码步骤:

1.在B页面中使用通知中心(NotificationCenter)调用post去赋值,同时发送通知消息
2.在B页面中需要实现“移除通知”,必须实现这个代码
3.在A页面中使用通知中心(NotificationCenter)调用addObserver来设置通知的监听事件
4.实现通知中心(NotificationCenter)的监听事件,并在方法里获取B页面传过来的值

注:NSNotification.Name(rawValue: "NotificationTest") ,在A、B页面中一定要一致,否则会无法接收传值

直接上代码

A页面代码:

import UIKit

class HTZViewController: UIViewController {
    //声明全局变量名
    var textLabel_1 = UILabel()
    override func viewDidLoad() {
        super.viewDidLoad()
        //声明变量,并初始化
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: 220, height: 50)
        ymBtn_01.setTitle("跳转发送通知页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
         //声明变量,并初始化
        let textLabel = UILabel()
        textLabel.font = .systemFont(ofSize: 20)
        textLabel.frame = CGRect(x: 50, y: ymBtn_01.frame.origin.y+150, width: 100, height: 50)
        textLabel.text = "接收传值:"
        view.addSubview(textLabel)
        
         //接收传值的标签
        textLabel_1.backgroundColor = .darkGray
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: (textLabel.frame.origin.x+textLabel.frame.size.width)+20, y: ymBtn_01.frame.origin.y+150, width: 200, height: 50)
        textLabel_1.text = "空值"
        textLabel_1.textColor = .white
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        view.addSubview(textLabel_1)
        
    }
    
    @objc func tiaozhuanyemianclick(sender:UIButton){
        
        let aTZVC = ATZViewController.init()
        aTZVC.title = "发送通知页面"
        aTZVC.view.backgroundColor = UIColor.init(named: "bgColor")
        
        /*
         创建通知中心
         设置监听方法
         设置通知的名字
         */
        NotificationCenter.default.addObserver(self, selector: #selector(login(_notification:)), name: NSNotification.Name(rawValue: "NotificationTest"), object: nil)
        //模态弹出
        self.present(aTZVC, animated: true, completion: nil)
    }
    
    //实现通知的监听方法,并在里面做好接收传值
    @objc private func login(_notification:Notification){
        //声明变量,并把获取的值赋值给变量
        let str = _notification.userInfo!["post"]
        //通过变量赋值给接收传值的标签
        textLabel_1.text = str as? String
        print("接收传值:",str!)
    }
}

B页面代码:

import UIKit

class ATZViewController: UIViewController {

    var textF = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: 220, height: 50)
        ymBtn_01.setTitle("发送通知,并返回传值", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        
        textF.frame = CGRect(x: 50, y: (ymBtn_01.frame.origin.y + ymBtn_01.frame.size.height) + 50, width: view.frame.size.width - 100, height: 50)
        textF.attributedPlaceholder = NSAttributedString(string: "请输入要传的值", attributes: [NSAttributedString.Key.foregroundColor : UIColor.yellow])
        textF.borderStyle = .line
        textF.textColor = .white
        textF.backgroundColor = .darkGray
        view.addSubview(textF)
        
    }
    //按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){

       //发送通知
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NotificationTest"), object:self ,userInfo: ["post":textF.text!])
        //退出模态窗口
        self.dismiss(animated: true, completion: nil)
    }
    //最后这里一定要记得移除通知
    deinit {
        print("移除通知")
        NotificationCenter.default.removeObserver(self)
    }
}

----------------------------------分割线---------------------------------------


3. 属性传值

传值描述:

A页面、B页面
A页面在跳转的同时通过B页面声明全局变量(可以是数组、字典)传值给B页面 -》B页面声明全局变量(可以是数组、字典),并接收A页面传来的值

实现代码步骤:

1.在B页面中声明全局变量,以便在其他页面中调用,同时使用全局变量赋值给UI控件
2.在A页面中跳转之前,A页面所传的值通过赋值给B页面属性进行传值

注:属性传值代码中有使用String(字符串)、Array(数组)、实例方法传值,这需要自己仔细看代码,梳理好流程再去写代码

直接上代码

A页面代码:

import UIKit

class HSXViewController: UIViewController {
    
    var textF = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: 220, height: 50)
        ymBtn_01.setTitle("跳转发送传值页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //传值的输入框
        textF.frame = CGRect(x: 50, y: (ymBtn_01.frame.origin.y + ymBtn_01.frame.size.height) + 50, width: view.frame.size.width - 100, height: 50)
        textF.attributedPlaceholder = NSAttributedString(string: "请输入要传的值", attributes: [NSAttributedString.Key.foregroundColor : UIColor.yellow])
        textF.borderStyle = .line
        textF.textColor = .white
        textF.backgroundColor = .darkGray
        view.addSubview(textF)
    }
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        
        let aSXVC = ASXViewController()
        aSXVC.myStr = textF.text!
        aSXVC.view.backgroundColor = .white
        //属性传值 - string
        aSXVC.title = "接收属性传值"
        /*
         如果不在输入框内填写想要传的值,那么下面的数组也可以实现属性传值
         数组,不会显示在页面上,但可以在下面控制台里打印出来
         */
        //属性传值 - Array
        let arrs:Array = ["宝马", "奔驰", "奥迪", "兰博基尼", "凯迪拉克", "法拉利"]
        //拷贝数组
        for item in arrs {
            aSXVC.arr.append(item)
        }
        /*
         属性传值 - 实例方法
         调用:在上级界面中,通过class名去调内部方法名
          class.方法名()
         */
        aSXVC.counter.increment(amount: 10203020301005060)
        
        //开始跳转界面
        self.navigationController?.pushViewController(aSXVC, animated: true)
    }
}

B页面代码:

import UIKit

class ASXViewController: UIViewController {
    //属性传值 - string
    var myStr = String()
    //属性传值 - array
    var arr:[String] = []
    //属性传值 - 全局引用实例方法 - 1
    var counter = Counter()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //返回上级界面的按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: 220, height: 50)
        ymBtn_01.setTitle("返回上个页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //接收传值的标签
        let textLabel = UILabel()
        textLabel.font = .systemFont(ofSize: 20)
        textLabel.frame = CGRect(x: 50, y: ymBtn_01.frame.origin.y+150, width: view.frame.size.width - 100, height: 50)
        textLabel.text = myStr
        textLabel.numberOfLines = 0
        textLabel.lineBreakMode = .byWordWrapping
        textLabel.backgroundColor = .darkGray
        textLabel.textColor = .white
        view.addSubview(textLabel)
    }
    
    // 视图将要显示时调用该方法
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("视图即将显示")
        /*
         由于viewDidLoad()无法接收传值,所以只能在视图即将显示的时候,来接收上级界面所传的值
         */
        //打印接收的数组
        for item in self.arr {
            //打印接收数组的值
            print(item)
        }
    }
    
    //实现按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        //开始返回上级界面
        self.navigationController?.popViewController(animated: true)
    }
}
// MARK: -  全局引用实例方法 - 2
/*
 通过实例方法也可以做到属性传值
 */
class Counter {
    func increment(amount:Int) {
        print("===amount:",amount)
    }
}


----------------------------------分割线---------------------------------------


4. 闭包传值(Block)

传值描述:

A页面、B页面
A页面-》B页面-》B页面声明闭包(Block),并在返回A页面的同时使用闭包传值(Block)-》A页面获取传值

实现代码步骤:

1.在B页面中声明全局的闭包(Block),并设置好要参数类型
2.在B页面中使用闭包(Block)赋值给闭包的参数
3.在A页面中在跳转页面之前,使用B页面的闭包给A页面的标签赋值

直接上代码

A页面代码:

import UIKit

class HBBViewController: UIViewController {
    //声明全局变量,并初始化
    var textLabel = UILabel()
    override func viewDidLoad() {
        super.viewDidLoad()
        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: view.frame.size.width - 100, height: 50)
        ymBtn_01.setTitle("跳转下级页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //接收传值的标签
        textLabel.font = .systemFont(ofSize: 20)
        textLabel.frame = CGRect(x: 50, y: ymBtn_01.frame.origin.y+150, width: view.frame.size.width - 100, height: 50)
        textLabel.text = "空值"
        textLabel.numberOfLines = 0
        textLabel.lineBreakMode = .byWordWrapping
        textLabel.backgroundColor = .darkGray
        textLabel.textColor = UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.6)
        view.addSubview(textLabel)
        
        //提示标签
        let textLabel_1 = UILabel()
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: 50, y: (textLabel.frame.origin.y+textLabel.frame.size.height)+50, width: view.frame.size.width - 100, height: 50)
        textLabel_1.text = "请先到下级页面中填写要传回的值"
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        textLabel_1.backgroundColor = .darkGray
        textLabel_1.textColor = .yellow
        textLabel_1.font = .systemFont(ofSize: 15)
        textLabel_1.textAlignment = .center
        view.addSubview(textLabel_1)
        
    }
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        let aBBVC = ABBViewController()
        aBBVC.view.backgroundColor = .white
        aBBVC.title = "传值界面"
        //调用闭包获取传值,并赋值给标签
        aBBVC.bbchange = {
            (title:String) in
            //赋值给标签
            self.textLabel.text = title
            print("接收传值:",title)
        }
        self.navigationController?.pushViewController(aBBVC, animated: true)
    }
    
}

B页面代码:

import UIKit

class ABBViewController: UIViewController {

    //声明全局闭包(Block)
    var bbchange:((_ title:String)->Void)?
    //声明全局变量,并初始化
     var textF = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: view.frame.size.width - 100, height: 50)
        ymBtn_01.setTitle("跳转到上级页面,并传回值", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //传值的输入框
        textF.frame = CGRect(x: 50, y: (ymBtn_01.frame.origin.y + ymBtn_01.frame.size.height) + 50, width: view.frame.size.width - 100, height: 50)
        textF.attributedPlaceholder = NSAttributedString(string: "请输入要传的值", attributes: [NSAttributedString.Key.foregroundColor : UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.5)])
        textF.borderStyle = .line
        textF.textColor = .white
        textF.backgroundColor = UIColor.init(red: 0.283, green: 0.290, blue: 0.293, alpha: 1)
        view.addSubview(textF)
        
        //提示标签
        let textLabel_1 = UILabel()
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: 50, y: (textF.frame.origin.y+textF.frame.size.height)+50, width: view.frame.size.width - 100, height: 50)
        textLabel_1.text = "请先上面的输入框中填写要传回的值"
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        textLabel_1.backgroundColor = UIColor.init(red: 0.238, green: 0.240, blue: 0.242, alpha: 0.5)
        textLabel_1.textColor = .yellow
        textLabel_1.font = .systemFont(ofSize: 15)
        textLabel_1.textAlignment = .center
        view.addSubview(textLabel_1)
        
    }
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        bbchange?(textF.text!)
        self.navigationController?.popViewController(animated: true)
    }

}

----------------------------------分割线---------------------------------------


5. 代理传值

传值描述:

A页面、B页面
A页面-》B页面-》B页面通过代理协议-》A页面

实现代码步骤:

1.在B页面中声明代理协议
2.在B页面中实现代理协议
3.在B页面中返回上级页面之前,使用代理协议赋值给参数
4.在A页面中跳转下级页面之前,设置B页面的代理协议
5.在A页面中实现B页面的代理协议,并在代理协议中通过参数获取传值,然后赋值给UI控件

直接上代码

A页面代码:

import UIKit
//添加代理协议
class HYDLViewController: UIViewController, HYDelegate {
    //实现代理方法
    func postValueToUpPage(str: String) {
        //获取值,并赋值给标签
        textLabel.text = str
    }
    
    //声明全局变量
    var textLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: view.frame.size.width - 100, height: 50)
        ymBtn_01.setTitle("跳转下级页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //接收传值的标签
        textLabel.font = .systemFont(ofSize: 20)
        textLabel.frame = CGRect(x: 50, y: ymBtn_01.frame.origin.y+150, width: view.frame.size.width - 100, height: 50)
        textLabel.text = "空值"
        textLabel.numberOfLines = 0
        textLabel.lineBreakMode = .byWordWrapping
        textLabel.backgroundColor = .darkGray
        textLabel.textColor = UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.6)
        view.addSubview(textLabel)
        
        //提示标签
        let textLabel_1 = UILabel()
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: 50, y: (textLabel.frame.origin.y+textLabel.frame.size.height)+50, width: view.frame.size.width - 100, height: 50)
        textLabel_1.text = "请先到下级页面中填写要传回的值"
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        textLabel_1.backgroundColor = .darkGray
        textLabel_1.textColor = .yellow
        textLabel_1.font = .systemFont(ofSize: 15)
        textLabel_1.textAlignment = .center
        view.addSubview(textLabel_1)
        
    }
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        //声明变量,并初始化类名
        let aYDLVC = AYDLViewController()
        //设置背景色,白色
        aYDLVC.view.backgroundColor = .white
        //设置导航标题
        aYDLVC.title = "传值界面"
        //设置代理协议,并遵守代理协议
        aYDLVC.delegate =  self
        //跳转下级页面
        self.navigationController?.pushViewController(aYDLVC, animated: true)
        
    }
}

B页面代码:

import UIKit

//实现代理协议
@objc protocol HYDelegate:NSObjectProtocol {
    //实现代理协议方法
    func postValueToUpPage(str:String)
}

//MARK: - 分割线
class AYDLViewController: UIViewController {
    
    //声明代理变量名,
    weak var delegate:HYDelegate?
    //声明变量名,并初始化
    var textF = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: view.frame.size.width - 100, height: 50)
        ymBtn_01.setTitle("跳转到上级页面,并传回值", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //传值的输入框
        textF.frame = CGRect(x: 50, y: (ymBtn_01.frame.origin.y + ymBtn_01.frame.size.height) + 50, width: view.frame.size.width - 100, height: 50)
        textF.attributedPlaceholder = NSAttributedString(string: "请输入要传的值", attributes: [NSAttributedString.Key.foregroundColor : UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.5)])
        textF.borderStyle = .line
        textF.textColor = .white
        textF.backgroundColor = UIColor.init(red: 0.283, green: 0.290, blue: 0.293, alpha: 1)
        view.addSubview(textF)
        
        let textLabel_1 = UILabel()
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: 50, y: (textF.frame.origin.y+textF.frame.size.height)+50, width: view.frame.size.width - 100, height: 50)
        textLabel_1.text = "请先上面的输入框中填写要传回的值"
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        textLabel_1.backgroundColor = UIColor.init(red: 0.238, green: 0.240, blue: 0.242, alpha: 0.5)
        textLabel_1.textColor = .yellow
        textLabel_1.font = .systemFont(ofSize: 15)
        textLabel_1.textAlignment = .center
        view.addSubview(textLabel_1)
        
        
    }
   //MARK: - 分割线
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        delegate?.postValueToUpPage(str: textF.text!)
        self.navigationController?.popViewController(animated: true)
    }
}


----------------------------------分割线---------------------------------------


6. NSUserDefaults传值

传值描述:

A页面、B页面
A页面-》B页面-》B页面使用UserDefaults类存储需要传的值-》A页面接收

实现代码步骤:

1.在B页面中返回上级页面之前,通过UserDefaults来存储需要传的值
2.在A页面中的生命周期 viewWillAppear() 里,通过 UserDefaults 内存的key来获取值

注:UserDefaults里存有String(字符串)、Array(数组)、Dictionary(字典),这里需要注意的是在获取值的时候,如果要获取数组,那么使用时是UserDefaults().array() 。如果是字典,那么使用时是UserDefaults(). dictionary() 。

直接上代码

A页面代码:

import UIKit

class UserDefaultsViewController: UIViewController {

    //声明全局变量
    var textLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: view.frame.size.width - 100, height: 50)
        ymBtn_01.setTitle("跳转下级页面", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //接收传值的标签
        textLabel.font = .systemFont(ofSize: 20)
        textLabel.frame = CGRect(x: 50, y: ymBtn_01.frame.origin.y+150, width: view.frame.size.width - 100, height: 50)
        textLabel.text = "空值"
        textLabel.numberOfLines = 0
        textLabel.lineBreakMode = .byWordWrapping
        textLabel.backgroundColor = .darkGray
        textLabel.textColor = UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.6)
        view.addSubview(textLabel)
        
        //提示标签
        let textLabel_1 = UILabel()
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: 50, y: (textLabel.frame.origin.y+textLabel.frame.size.height)+50, width: view.frame.size.width - 100, height: 50)
        textLabel_1.text = "请先到下级页面中填写要传回的值"
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        textLabel_1.backgroundColor = .darkGray
        textLabel_1.textColor = .yellow
        textLabel_1.font = .systemFont(ofSize: 15)
        textLabel_1.textAlignment = .center
        view.addSubview(textLabel_1)
        
    }
    //视图即将显示
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        /*------------------------------*/
        /*
         Swift之UserDefaults数据存储 https://www.jianshu.com/p/99660cadfe16
         1、存储各种类型的数据
         2、获取各种类型的存储数据
         */
        //获取数组,就需要使用 xxx.array(key)
        let strArray = UserDefaults().array(forKey: "userNameArray")
        print("====array:",strArray as Any)
        
        //获取数组,就需要使用 xxx.dictionary(key)
        let strDic = UserDefaults().dictionary(forKey: "userNameDictinary")
        print("====Dictinary:",strDic as Any)
        
        //声明变量,获取userdefaults中的值,并赋值
        let str = UserDefaults().string(forKey: "userName")
        //赋值给标签
        textLabel.text = str
    }
    
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        //声明变量,并初始化类名
        let aUDVC = AUDViewController()
        //设置背景色,白色
        aUDVC.view.backgroundColor = .white
        //设置导航标题
        aUDVC.title = "传值界面"
        //跳转下级页面
        self.navigationController?.pushViewController(aUDVC, animated: true)
        
    }
}

B页面代码:

import UIKit

class AUDViewController: UIViewController {

    //声明变量名,并初始化
    var textF = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //传值按钮
        let ymBtn_01 = UIButton()
        ymBtn_01.frame = CGRect(x: 50, y: 130, width: view.frame.size.width - 100, height: 50)
        ymBtn_01.setTitle("跳转到上级页面,并传回值", for: .normal)
        ymBtn_01.backgroundColor = .brown
        ymBtn_01.tag = 10001
        ymBtn_01.addTarget(self, action: #selector(tiaozhuanyemianclick(sender:)), for: .touchUpInside)
        view.addSubview(ymBtn_01)
        
        //传值的输入框
        textF.frame = CGRect(x: 50, y: (ymBtn_01.frame.origin.y + ymBtn_01.frame.size.height) + 50, width: view.frame.size.width - 100, height: 50)
        textF.attributedPlaceholder = NSAttributedString(string: "请输入要传的值", attributes: [NSAttributedString.Key.foregroundColor : UIColor.init(red: 1.000, green: 1.000, blue: 1.000, alpha: 0.5)])
        textF.borderStyle = .line
        textF.textColor = .white
        textF.backgroundColor = UIColor.init(red: 0.283, green: 0.290, blue: 0.293, alpha: 1)
        view.addSubview(textF)
        
        let textLabel_1 = UILabel()
        textLabel_1.font = .systemFont(ofSize: 20)
        textLabel_1.frame = CGRect(x: 50, y: (textF.frame.origin.y+textF.frame.size.height)+50, width: view.frame.size.width - 100, height: 50)
        textLabel_1.text = "请先上面的输入框中填写要传回的值"
        textLabel_1.numberOfLines = 0
        textLabel_1.lineBreakMode = .byWordWrapping
        textLabel_1.backgroundColor = UIColor.init(red: 0.238, green: 0.240, blue: 0.242, alpha: 0.5)
        textLabel_1.textColor = .yellow
        textLabel_1.font = .systemFont(ofSize: 15)
        textLabel_1.textAlignment = .center
        view.addSubview(textLabel_1)
        
        
    }
    
    //实现传值按钮的监听方法
    @objc func tiaozhuanyemianclick(sender:UIButton){
        //使用UserDefaults把需要传的值,先存到本地沙盒中,存储是根据key来存储的,一个key对应一个值(可以是可变数组,或可变字典)
        /*
        Swift之UserDefaults数据存储 https://www.jianshu.com/p/99660cadfe16
        1、存储各个类型的数据
        2、获取各个类型的存储数据
        */
        //声明数组变量名,并填入数据
        let array =  ["宝马", "奔驰", "奥迪", "兰博基尼", "凯迪拉克", "法拉利"]
        //通过key来存储数组
        UserDefaults().set(array, forKey: "userNameArray")
        //声明字典变量名,并填入数据
        let dic =  ["BM":"宝马", "BC":"奔驰", "AD":"奥迪", "LBJN":"兰博基尼", "KDLK":"凯迪拉克", "FLL":"法拉利"]
        //通过key来存储字典
        UserDefaults().set(dic, forKey: "userNameDictinary")
        //通过key来存储字符串
        UserDefaults().set(textF.text!, forKey: "userName")
        //返回上级页面
        self.navigationController?.popViewController(animated: true)
    }
}

----------------------------------分割线---------------------------------------


传值的几种方式,根据自己的需求来使用,其中,有几个可以实现正向传值、反向传值,这里就不再写了,太长了,也太累,原谅我的懒惰吧!

代码请到gitee上下载:https://gitee.com/h8900961/pass-value-demo

有任何问题,请留言,我会第一时间去处理。
谢谢,浏览!

你可能感兴趣的:(2020-08-19 swift 传值的几个方式)