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

Swift:如何通过委托从初始视图控制器向第二个视图控制器传值?

Troubleshooting Your Swift Delegate Setup for Passing Data to a Second VC

Hey there! Let's figure out why your delegate isn't passing data from the initial ViewController to RVC—you're close, but there's a key mistake in how you're connecting the two view controllers.

The Core Issue

In your RVC class, you're creating a brand new instance of ViewController with let vc = ViewController(). This is not the same ViewController instance that's actually displayed on screen! When you set vc.data = self, you're only configuring this new, unused instance—your original, visible ViewController's data property remains nil. That's why when you tap the send button, data?.sendData(data: msg) does nothing (optional chaining skips the call when data is nil).

Fixed Code & Step-by-Step Fixes

1. Update the Initial View Controller (ViewController)

First, add a prepare(for:sender:) method to handle the segue transition—this is where you'll connect the real ViewController instance to RVC:

import UIKit

// Move the protocol outside the class (optional but cleaner)
protocol DataDelegate: class { // Add `class` to allow weak references
    func sendData(data: String)
}

class ViewController: UIViewController {
    // Use weak to avoid retain cycles
    weak var data: DataDelegate?
    @IBOutlet weak var text: UITextField!
    @IBOutlet weak var send: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func send(_ sender: Any) {
        // Safely unwrap the text to avoid crashes
        guard let msg = text.text, !msg.isEmpty else {
            print("Empty message, not sending")
            return
        }
        data?.sendData(data: msg)
        print("SENDING MESSAGE: \(msg)")
    }
    
    // This runs right before the segue to RVC
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Make sure we're navigating to RVC
        if let destinationVC = segue.destination as? RVC {
            // Set the delegate to the actual RVC instance we're about to show
            self.data = destinationVC
        }
    }
}

2. Fix the Second View Controller (RVC)

Remove the unused ViewController instance and the line that sets its delegate—we don't need them anymore:

import UIKit

class RVC: UIViewController, DataDelegate {
    @IBOutlet weak var delegationLabel: UILabel!
    @IBOutlet weak var message: UILabel!
    @IBOutlet weak var back: UIButton!
    
    // DELETE THIS LINE: let vc = ViewController()
    
    func sendData(data: String) {
        print("DATA SENT")
        print(data)
        message.text = data
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("LOADED")
        // DELETE THIS LINE: vc.data = self
    }
}

Key Additional Tips

  • Weak Delegate: By making DataDelegate inherit from class and declaring var data: DataDelegate? as weak, you prevent retain cycles (memory leaks) that would happen if both view controllers held strong references to each other.
  • Safe Optional Handling: Using guard let for text.text avoids crashes if the text field is empty or nil.
  • Segue Setup: Make sure your storyboard has a segue from ViewController to RVC (e.g., a show segue from the send button or a navigation controller), so the prepare(for:sender:) method runs when you navigate.

Now when you tap the send button in ViewController, it will call sendData(_:) on the actual RVC instance that's displayed, and your message will show up in the message label!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:48:11