You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中从secondVC返回时向ViewController传递标签文本的实现方法

解决返回时secondVC向ViewController传递数据的问题

需求是:点击导航栏返回按钮时,把secondVC里resultLabel的文本传给ViewController的nameLabel。你之前用prepare(for:sender:)没用是因为这个方法是正向跳转(从VC到secondVC)时执行的,这时候secondVC的resultLabel还没有用户输入的内容,反向传值得在返回动作触发时处理。

下面给两种常用的实现方式:


方法一:代理模式

代理是iOS反向传值的经典方案,步骤如下:

  1. 在secondVC中定义代理协议
    给secondVC添加代理协议,规定数据传递的方法:

    import UIKit
    
    // 定义代理协议
    protocol SecondVCDelegate: AnyObject {
        func secondVC(_ vc: secondVC, didReturnWithText text: String?)
    }
    
    class secondVC: UIViewController {
        @IBOutlet weak var nameField: UITextField!
        @IBOutlet weak var resultLabel: UILabel!
        
        // 代理属性,用weak避免循环引用
        weak var delegate: SecondVCDelegate?
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        
        @IBAction func saveClicked(_ sender: Any) {
            resultLabel.text = nameField.text
        }
        
        // 监听返回动作,判断当前VC是否被弹出导航栈
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            if isMovingFromParent {
                delegate?.secondVC(self, didReturnWithText: resultLabel.text)
            }
        }
    }
    
  2. 让ViewController遵守代理协议并实现方法
    修改ViewController代码,在跳转时设置代理,实现代理方法更新标签:

    import UIKit
    
    // 遵守代理协议
    class ViewController: UIViewController, SecondVCDelegate {
    
        @IBOutlet weak var nameLabel: UILabel!
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        @IBAction func goVC2(_ sender: Any) {
            performSegue(withIdentifier: "toVC2", sender: nil)
        }
        
        // 正向跳转时设置代理
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "toVC2" {
                let vc = segue.destination as! secondVC
                vc.delegate = self
            }
        }
        
        // 实现代理方法,接收数据更新标签
        func secondVC(_ vc: secondVC, didReturnWithText text: String?) {
            nameLabel.text = text
        }
    }
    

方法二:闭包回调

闭包是更简洁的反向传值方式,代码量更少:

  1. 在secondVC中添加闭包属性
    定义闭包用于传递数据,在返回时调用:

    import UIKit
    
    class secondVC: UIViewController {
        @IBOutlet weak var nameField: UITextField!
        @IBOutlet weak var resultLabel: UILabel!
        
        // 定义可选闭包,避免未赋值导致崩溃
        var onBack: ((String?) -> Void)?
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        
        @IBAction func saveClicked(_ sender: Any) {
            resultLabel.text = nameField.text
        }
        
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            if isMovingFromParent {
                // 调用闭包传递数据
                onBack?(resultLabel.text)
            }
        }
    }
    
  2. 在ViewController中设置闭包
    在跳转时给secondVC的闭包赋值,接收数据更新标签:

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var nameLabel: UILabel!
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        @IBAction func goVC2(_ sender: Any) {
            performSegue(withIdentifier: "toVC2", sender: nil)
        }
        
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "toVC2" {
                let vc = segue.destination as! secondVC
                // 设置闭包,用weak self避免循环引用
                vc.onBack = { [weak self] text in
                    self?.nameLabel.text = text
                }
            }
        }
    }
    

注意点

  • 不管用代理还是闭包,都要用weak引用ViewController,避免循环引用导致内存泄漏。
  • isMovingFromParent用来判断当前VC是否被弹出导航栈,确保只有点击返回按钮时才传递数据,排除其他页面消失场景(比如push新VC)。

内容的提问来源于stack exchange,提问作者ShakyAardvark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 23:15:36