gpt4 book ai didi

ios - 委托(delegate)/协议(protocol)将数据从一个 View Controller 传递到另一个

转载 作者:行者123 更新时间:2023-11-28 10:46:19 24 4
gpt4 key购买 nike

尝试使用协议(protocol)和扩展将数据从一个 View Controller MainScreenVC 传递到另一个 RatesVC,但这不起作用,应用程序每次都崩溃。我清楚地看到第二个 VC 上的代码存在问题(因为在第一个 VC 上执行操作后打印显示正确的数据)但不确定哪里出错了。

StoryBoard and 1st VC Example Second VC

第一个 View Controller

import UIKit

protocol transferNameOfCurrency {
func currencySelected(nameOfCurrency: String)
}

class MainScreenVC: UIViewController {

var transferCurrencyDelegate: transferNameOfCurrency?
var nameOfTheCurrency: String?

@IBAction func updateRates(_ sender: Any) {
nameOfTheCurrency = "EUR"
transferCurrencyDelegate?.currencySelected(nameOfCurrency:
nameOfTheCurrency)
print(nameOfTheCurrency)

}
}

第二个 View Controller

import UIKit

class RatesVC: UIViewController {
var currencySelected: String?

override func viewDidLoad() {
super.viewDidLoad()

if let push = self.storyboard?.instantiateViewController(withIdentifier: "MainScreenVC") as? MainScreenVC
{
push.transferCurrencyDelegate = self
}

// Do any additional setup after loading the view.
}
}

extension RatesVC: transferNameOfCurrency {
func currencySelected(nameOfCurrency: String) {
currencySelected = nameOfCurrency
print(currencySelected)
}

}

最佳答案

最明显的问题在于:

if let push = self.storyboard?.instantiateViewController(withIdentifier: "MainScreenVC") as? MainScreenVC {
push.transferCurrencyDelegate = self
}

您必须意识到 instantiateViewController 创建了一个 View Controller - 它不是对显示在屏幕上的 View Controller 的引用。在该代码中,您刚刚创建了一个全新的 View Controller ,然后将其委托(delegate)设置为 self,除此之外别无其他。

在不知道上下文的情况下,很难提出任何建议 - prepare(for:) segue 可能是您要设置委托(delegate)的地方。无论如何,问题是您必须获得对屏幕上显示的 Controller 的引用,该 Controller 应该对这些事件使用react。

此外,从内存管理方面来说,您真的应该考虑将 delegate 属性设置为 weak 属性以防止内存泄漏。

编辑

所以在看到您在 link 提供的最小工作示例之后,我想我可以提供有关如何将该字符串获取到 SecondVC 的解决方案。

你的第一个带有评论的 View Controller :

import UIKit

class ViewController: UIViewController {

var newLine: String = "EUR"

@IBAction func push(_ sender: Any) {
// here the secondVC does not exist yet, calling delegate.transferWord() here would have no sense
// performSegue will create that secondVC, but now it does not exist, nor it is set up as the delegate
self.performSegue(withIdentifier: "ViewController", sender: navigationController)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let secondVC = segue.destination as? SecondVC, segue.identifier == "ViewController" {
// at this moment secondVC did not load its view yet, trying to access it would cause crash
// because transferWord tries to set label.text directly, we need to make sure that label
// is already set (for experiment you can try comment out next line)
secondVC.loadViewIfNeeded()
// but here secondVC exist, so lets call transferWord on it
secondVC.transferWord(word: newLine)
}
}
}

这里不需要委托(delegate),因为你的 ViewController 是将 SecondVC 推送到 Navigation Controller 的那个 - 这意味着你可以在 prepare 中直接访问它(for:),如上所示。

现在 SecondVC 非常简单(我省略了不必要的代码):

import UIKit

class SecondVC: UIViewController {

@IBOutlet weak var label: UILabel!

func transferWord(word: String) {
label.text = word
}
}

Storyboard可以保持原样。

关于ios - 委托(delegate)/协议(protocol)将数据从一个 View Controller 传递到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48403913/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com