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

Navigation Controller中如何保留第二个ViewController的输入值?

嘿,这个问题我之前也碰到过!核心原因其实是你每次跳转到SecondVC的时候,都用instantiateViewController创建了一个全新的实例——之前输入的内容都在旧实例里,新实例当然是空的啦。下面给你几个靠谱的解决方案,按需选就行:

解决方案1:复用同一个SecondVC实例

这是最直接的办法,在FirstVC里保存一个SecondVC的引用,只在第一次需要的时候实例化它,之后跳转都用这个已存在的实例。

代码示例(在FirstVC中):

// 声明可选属性,用来缓存SecondVC实例
private var secondVC: SecondVC?

// 跳转触发方法(比如按钮点击)
@IBAction func navigateToSecondVC(_ sender: UIButton) {
    // 只有当实例不存在时才创建
    if secondVC == nil {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        secondVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
    }
    navigationController?.show(secondVC!, sender: self)
}

这样每次跳转都是同一个SecondVC实例,里面的TextField内容自然会保留。注意:如果你的SecondVC需要根据FirstVC的状态动态更新内容,记得在跳转前做相应的重置或更新操作。

解决方案2:用ViewModel共享数据(推荐,更符合架构设计)

如果你的项目后续可能有更多页面需要共享数据,或者不想耦合VC实例,用ViewModel是更优雅的选择。创建一个独立的ViewModel类来保存输入数据,让两个VC都绑定到这个ViewModel的属性上。

步骤:

  1. 先创建ViewModel类:
class FormViewModel {
    // 对应四个TextField的属性
    var field1: String = ""
    var field2: String = ""
    var field3: String = ""
    var field4: String = ""
}
  1. 在FirstVC中初始化ViewModel,并传递给SecondVC:
// FirstVC中声明ViewModel实例
private let formViewModel = FormViewModel()

// 跳转方法
@IBAction func navigateToSecondVC(_ sender: UIButton) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let destinationVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
    // 把ViewModel传给SecondVC
    destinationVC.viewModel = formViewModel
    navigationController?.show(destinationVC, sender: self)
}
  1. 在SecondVC中绑定TextField和ViewModel:
// SecondVC中声明ViewModel属性
var viewModel: FormViewModel!

// 监听TextField编辑事件(可以给每个TextField设置tag区分)
@IBAction func textFieldDidChange(_ sender: UITextField) {
    switch sender.tag {
    case 1: viewModel.field1 = sender.text ?? ""
    case 2: viewModel.field2 = sender.text ?? ""
    case 3: viewModel.field3 = sender.text ?? ""
    case 4: viewModel.field4 = sender.text ?? ""
    default: break
    }
}

// 在页面即将显示时,把ViewModel的数据同步到TextField
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    textField1.text = viewModel.field1
    textField2.text = viewModel.field2
    textField3.text = viewModel.field3
    textField4.text = viewModel.field4
}

这个方案的好处是数据和VC分离,就算销毁了SecondVC实例,数据依然保存在ViewModel里,下次创建新的SecondVC时,只要传递ViewModel就能恢复之前的输入内容。而且如果以后有其他页面需要用到这些数据,直接复用ViewModel就行。

解决方案3:通过闭包传递数据回FirstVC

如果不想复用SecondVC实例,也不想用ViewModel,可以在SecondVC返回的时候把输入数据传递给FirstVC保存,下次跳转时再把数据传给新的SecondVC。

步骤:

  1. 在SecondVC中定义闭包用来传递数据:
// 定义闭包,用于返回时传递TextField数据
var onDataSaved: ((String, String, String, String) -> Void)?

// 返回按钮的点击方法
@IBAction func goBackToFirstVC(_ sender: UIButton) {
    // 把当前TextField的值通过闭包传递回去
    onDataSaved?(textField1.text ?? "", textField2.text ?? "", textField3.text ?? "", textField4.text ?? "")
    navigationController?.popViewController(animated: true)
}
  1. 在FirstVC中保存数据,并在跳转时传递给新的SecondVC:
// FirstVC中保存SecondVC的输入数据
private var secondVCInputData: (field1: String, field2: String, field3: String, field4: String) = ("", "", "", "")

// 跳转方法
@IBAction func navigateToSecondVC(_ sender: UIButton) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let destinationVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
    // 把之前保存的数据赋值给新的SecondVC的TextField
    destinationVC.textField1.text = secondVCInputData.field1
    destinationVC.textField2.text = secondVCInputData.field2
    destinationVC.textField3.text = secondVCInputData.field3
    destinationVC.textField4.text = secondVCInputData.field4
    // 设置闭包,接收返回的数据
    destinationVC.onDataSaved = { [weak self] field1, field2, field3, field4 in
        self?.secondVCInputData = (field1, field2, field3, field4)
    }
    navigationController?.show(destinationVC, sender: self)
}

这个方案适合简单场景,但如果TextField数量多或者后续有扩展,代码会变得繁琐,不如ViewModel优雅。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:31:13