【问题标题】:Call a UITableViewFunction from another view从另一个视图调用表视图函数
【发布时间】:2018-03-20 14:27:06
【问题描述】:

我有一个由UITableView 调用的function,它根据它包含的内容更新钱包值(因此由tableView 调用)。这是WalletViewController 的一部分,用户可以在其中更新他的钱包所包含的内容。

我希望能够从MainViewController 调用此函数,其中还显示了钱包值,因此当用户刷新数据时它是最新的,目前仅发生钱包值更新功能当你加载 WalletViewControllerreloadData() 时被调用。

如何才能刷新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,请保留前者的引用。

标签: ios swift function uitableview core-data


【解决方案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() 将是WalletViewControllerupdateWalletValue() 的更新版本,其中的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 会出现在MainViewControllerupdateWalletLabel() 中?
  • addObsever 将在 MainViewController 中,并在选择器“updateWalletLabel()”中写入方法,并且 post 将在钱包值更改的 walletViewController 中。
猜你喜欢
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多