从另一个视图调用表视图函数
Posted
技术标签:
【中文标题】从另一个视图调用表视图函数【英文标题】:Call a UITableViewFunction from another view 【发布时间】:2018-03-20 14:27:06 【问题描述】:我有一个由UITableView
调用的function
,它根据它包含的内容更新钱包值(因此由tableView 调用)。这是WalletViewController
的一部分,用户可以在其中更新他的钱包所包含的内容。
我希望能够从MainViewController
调用此函数,其中还显示了钱包值,因此当用户刷新数据时它是最新的,目前仅发生钱包值更新功能当你加载 WalletViewController
和 reloadData()
时被调用。
如何才能刷新MainViewController
中的值?
数值更新功能的WalletViewController代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! WalletTableViewCell
cell.delegate = self
cell.amountTextField.delegate = self
updateCellValueLabel(cell, atRow: indexPath.row)
return cell
func updateCellValueLabel(_ walletTableViewCell: WalletTableViewCell, atRow row: Int)
//... calculations for each wallet's object are happening here ...
CoreDataHandler.editObject(editObject: selectedAmount, amount: amount, amountValue: currentAmountValue)
// <--- calculations result for each object is saved to CoreData
updateWalletValue()
updateWalletLabel()
func updateWalletValue()
var items : [CryptosMO] = []
if CoreDataHandler.fetchObject() != nil
items = CoreDataHandler.fetchObject()!
// <--- Calculations result are fetched from CoreData
total = items.reduce(0.0, $0 + Double($1.amountValue)! )
// <--- Objects values are added together to get the wallet's grand total
WalletTableViewController.staticTotal = total
func updateWalletLabel()
walletValueLabel.text = formatter.string(from: NSNumber(value: total))
MainViewController钱包更新功能至今:
func updateWalletLabel()
WalletTableViewController.init().updateWalletValue()
walletValue.text = formatter.string(from: NSNumber(value: WalletTableViewController.staticTotal))
我想我应该从核心数据中获取钱包对象的数量并从MainViewController
重新计算以获取最新值?或者有没有更简单的解决方案来调用整个tableView
函数?
【问题讨论】:
在 MainViewController 中使用 post 通知和 addObserver。 请注意WalletTableViewController()
创建了控制器的一个新实例,它不是故事板中的实例。您需要对控制器的实际引用。
@MRizwan33 会是什么样子?
@PhillipMills 对不起,您是什么意思?我知道这不是你的意思,但我的核心数据功能不在视图控制器中。
如果WalletTableViewController
来自MainViewController
,请保留前者的引用。
【参考方案1】:
有几种方法可以做到这一点。如果您想走“发布通知”路线,@MRizwan33 的答案将起作用。
我通常会做的另一种选择是从您的MainViewController
获取对您的WalletViewController
的引用,然后直接在WalletViewControllerInstance
上拨打电话:
class MainViewController: UIViewController
// Local variable to cache instance of WalletViewController
var walletVC: WalletViewController?
func functionWhereWalletViewControllerIsInstantiated()
// Save the reference to the WalletViewController instance
walletVC = self.storyboard?.instantiateViewController(
withIdentifier: "WalletViewControllerIdentifier") as!
WalletViewController
func someFuncWhereYouWantToUpdateWalletViewController()
// Call the function on your cached WalletViewController
// instance that performs the refresh
walletVC.doTheUpdate()
如果你在推送的地方实例化walletVC
,你可以这样做:
func functionWhereWalletVcIsPushed()
if (walletVC == null)
walletVC = self.storyboard?.instantiateViewController(
withIdentifier: "WalletViewControllerIdentifier") as!
WalletViewController
// Push the view controller
你也可以让属性变得懒惰:
lazy var walletVC: WalletViewController =
return self.storyboard?.instantiateViewController(
withIdentifier: "WalletViewControllerIdentifier") as!
WalletViewController
(我不是 Swift 专家,所以您需要仔细检查语法)
【讨论】:
非常感谢!我能理解你在这里做什么,这很棒!然后doTheUpdate()
将是WalletViewController
的updateWalletValue()
的更新版本,其中的reloadData()
表是否太正确?
对不起,我在推送视图时打电话给instantiateViewController(withIdentifier:)
。我现在应该什么时候打电话?谢谢!
如果你愿意,你仍然可以在那里做。最简单的方法是在推送之前检查if (walletVC == null) /* Instantiate */
。另一种选择是将walletVC
设为惰性属性,以便在首次访问时对其进行实例化。
好吧,一切都设置好了,不幸的是,用walletVC.doTheUpdate()
调用tableView.reloadData()
来获取最新数据并更新钱包值会导致应用程序在Found nil
崩溃,这是有道理的,因为tableView
不是显示。我能做什么?
您似乎需要重新设计WalletViewController
中的更新功能的工作方式。显然你不能在 nil TableView 上调用reloadData()
。您要在“MainViewController”中显示的究竟是什么?如果它是在 WalletViewController
中计算并保存在其他位置(CoreData?)的某个值,您应该考虑将该逻辑移动到另一个类并将其从 MainViewController
传递到 WalletViewController
作为依赖项。【参考方案2】:
在您想要调用更新另一个视图的位置使用此行。
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
添加将发生更新的这些行:
NotificationCenter.default.addObserver(self, selector: #selector("Your Method Name Which you want to call on change like (reloadTableView)"), name: Notification.Name("NotificationIdentifier"), object: nil)
【讨论】:
非常感谢!你能指点我把它们放在我的代码中的什么地方吗?我猜addObserver
会出现在WalletViewController
的某个地方,而post
会出现在MainViewController
的updateWalletLabel()
中?
addObsever 将在 MainViewController 中,并在选择器“updateWalletLabel()”中写入方法,并且 post 将在钱包值更改的 walletViewController 中。以上是关于从另一个视图调用表视图函数的主要内容,如果未能解决你的问题,请参考以下文章