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

Swift委托模式问题:如何在两个ViewController间传递文本?

Swift纯代码实现两个ViewController间传值(文本框→标签)

问题分析

你当前的代理模式存在两处关键问题:

  1. 未建立代理关联:创建GameViewController实例后,没有将其赋值给MainViewController的delegate属性,导致delegate?.getWord调用时实际为nil,代理方法不会执行。
  2. 调用时机过早:即使代理关联成功,跳转前调用代理方法时,GameViewController的视图还未加载完成,直接设置标签文本可能不生效。

解决方案

方案1:修复代理模式

调整代理关联逻辑,并延迟标签文本设置时机:

修改MainViewController的startGame方法:

@objc func startGame() {
    guard let inputWord = mainView.wordTf.text, inputWord.count > 7 else {
        print("Slishkom korotkoe slovo")
        return
    }
    
    let vc = GameViewController()
    vc.modalPresentationStyle = .fullScreen
    // 关键:将GameViewController实例绑定为代理对象
    self.delegate = vc
    delegate?.getWord(word: inputWord)
    self.present(vc, animated: true)
}

修改GameViewController代码,先存储传值再在视图加载后设置标签:

class GameViewController: UIViewController {
    let gameView = GameView()
    // 新增属性暂存传递的文字
    private var receivedWord: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = gameView
        addTargets()
        // 视图加载完成后设置标签文本
        if let word = receivedWord {
            gameView.bigWord.text = word
        }
    }
    
    func addTargets() {
        gameView.backButton.addTarget(self, action: #selector(dismissSelf), for: .touchUpInside)
    }
    
    @objc func dismissSelf() {
        self.dismiss(animated: true)
    }
}

extension GameViewController: DataDelegate {
    func getWord(word: String) {
        // 先存储文字,等待视图加载完成后再设置
        receivedWord = word
    }
}

方案2:直接属性传值(更适合初学者)

无需代理,直接给GameViewController添加公开属性实现传值:

修改GameViewController,新增传值属性:

class GameViewController: UIViewController {
    let gameView = GameView()
    // 新增公开属性,用于接收传递的文字
    var passedWord: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = gameView
        addTargets()
        // 视图加载完成后设置标签文本
        if let word = passedWord {
            gameView.bigWord.text = word
        }
    }
    
    func addTargets() {
        gameView.backButton.addTarget(self, action: #selector(dismissSelf), for: .touchUpInside)
    }
    
    @objc func dismissSelf() {
        self.dismiss(animated: true)
    }
}

修改MainViewController的startGame方法:

@objc func startGame() {
    guard let inputWord = mainView.wordTf.text, inputWord.count > 7 else {
        print("Slishkom korotkoe slovo")
        return
    }
    
    let vc = GameViewController()
    vc.modalPresentationStyle = .fullScreen
    // 直接给属性赋值传递文字
    vc.passedWord = inputWord
    self.present(vc, animated: true)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:45:23