如何从创建的 UIViewController 中的另一个 UIViewController 执行功能

Posted

技术标签:

【中文标题】如何从创建的 UIViewController 中的另一个 UIViewController 执行功能【英文标题】:How to execute a function from another UIViewController in the UIViewController where was created 【发布时间】:2018-07-04 07:26:21 【问题描述】:

我有 2 个 UIViewController:ProductsVC 和 CartVC。在 CartVC 中,我有一个功能可以从我的购物车中清除我的所有产品。 我想要做的是,当我在 ProductsVC 中时,我从 CoreData 中删除了一个产品,然后从第二个 VC 即 CartVC 中清除我的所有产品。所以我需要告诉那个函数在那里执行。

这是我的代码:

// First VC
class ProductsViewController: UIViewController

    // Function to delete a Product from the table view and also from CoreData
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 

        let productEntity = Constants.productEntity
        let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let product = productsArray[indexPath.row]
        // -----------   HERE I NEED TO TELL TO "clearAllProducts()" to be executed in the CartVC so when I click on the Cart button, there will be 0 products.
        if editingStyle == .delete 
            managedContext.delete(product)
            do 
                try managedContext.save()
             catch let error as NSError 
                print(Constants.errorDeletingProduct + "\(error.userInfo)")
            
        

        // fetch new data from DB and reload products table view
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: productEntity)
        do 
            productsArray = try managedContext.fetch(fetchRequest) as! [Product]
         catch let error as NSError 
            print(Constants.errorFetchingData + "\(error.userInfo)")
        
        productsTableView.reloadData()
    



// Second VC
class CartViewController: UIViewController 


// Clear all products from the cart
    @IBAction func clearAllProducts(_ sender: Any) 

        // Reset Cart tableView
        productsInCartArray = [Product]()
        productPricesArray = [Float]()
        totalSum = 0
        self.tabBarController?.tabBar.items?[1].badgeValue = String(0)

        // Remove selected products from ProductsViewController
        ((self.tabBarController?.viewControllers![0] as! UINavigationController).topViewController as! ProductsViewController).selectedProductsArray = [Product]()
        ((self.tabBarController?.viewControllers![0] as! UINavigationController).topViewController as! ProductsViewController).priceForSelectedProductsArray = [Float]()
        ((self.tabBarController?.viewControllers![0] as! UINavigationController).topViewController as! ProductsViewController).counterItem = 0
        ((self.tabBarController?.viewControllers![0] as! UINavigationController).topViewController as! ProductsViewController).numberOfProductsInCartLabel.text = String(0)
        UIApplication.shared.applicationIconBadgeNumber = 0
        cartTableView.reloadData()
    

这是一张图片,看看我为什么要这样做:

感谢您的宝贵时间!

【问题讨论】:

productVC 和 CartVC 是如何关联的? productVC 是否呈现/推送 CartVC 或 productVC 是容器并且 CartVC 在其中呈现为 childVC?在任何情况下,您都可以参考 CartVC 并直接在其上调用方法 两个 ViewController 都与 TabBarController 连接,如下图所示:ibb.co/bRqTpy 你只需要一个视图控制器的全局变量在你的 vc 中,你想从那里调用他们的 vc 的方法 我不想使用 Globals....是一种不好的做法。 它的坏习惯如何 【参考方案1】:

你有两个选择:

1: 如果您的一个视图控制器被另一个视图控制器调用,那么您可以在调用的 VC 中拥有一个委托属性,并将委托的值分配给第一个视图控制器,然后通常调用委托方法。例如self.delegate?.myFunc()

2: 如果您的视图控制器不直接相关,那么您可以使用NotificationCenter 向所有监听视图发送通知。 在你的情况下,这个可能更合适。

【讨论】:

【参考方案2】:

我用一个小函数解决了我的问题,它用空值实例化我的数组。功能就是这个:

// Remove all products from the cart when one ore more products are deleted from the CoreData.
func removeAllProductsFromCart()

    selectedProductsArray = [Product]()
    priceForSelectedProductsArray = [Float]()
    counterItem = 0
    numberOfProductsInCartLabel.text = String(0)
    self.tabBarController?.tabBar.items?[1].badgeValue = String(0)
    UIApplication.shared.applicationIconBadgeNumber = 0

我在这里调用这个函数:

if editingStyle == .delete 
    managedContext.delete(product)
    do 
        removeAllProductsFromCart()
        try managedContext.save()
     catch let error as NSError 
        print(Constants.errorDeletingProduct + "\(error.userInfo)")
    

【讨论】:

【参考方案3】:

我认为共享数据的正确方法是使用自定义标签栏控制器,并且您的数组应该是标签栏的属性。

这样,两个 VC 都可以访问数据,并且可以根据需要使用标签栏控制器的自定义方法清除数据。

【讨论】:

以上是关于如何从创建的 UIViewController 中的另一个 UIViewController 执行功能的主要内容,如果未能解决你的问题,请参考以下文章

如何从情节提要属性为 nil 的动态创建的 UIViewController 执行SegueWithIdentifier()

如何从 .XIB 加载 UIViewController?

如何将动作从 SKScene 组件传播到 UIViewController

从 Tableview 自定义单元格翻转过渡到 UIViewController

加载随机 UIViewController?

以编程方式创建的 UIViewController 加载界面构建器 view.xib 文件