Ios 从自定义UIViewController导航到不带segue的TabBarController

Ios 从自定义UIViewController导航到不带segue的TabBarController,ios,swift,uiviewcontroller,uitabbarcontroller,Ios,Swift,Uiviewcontroller,Uitabbarcontroller,当我从自定义UIViewController导航到TabBarController的第二个选项卡(当然是另一个UIViewController)时,我遇到了一个问题。 如果我从AdminPanel导航到Products,则不会崩溃,因为我有一个从Products到AdminPanel的推送操作。但是从AdminPanel到Cart,我没有任何推送功能 下面是一张有bug的图片: 这是错误:“无法将“MyAppName.AdminPanelViewController”(0x10e878418)

当我从自定义UIViewController导航到TabBarController的第二个选项卡(当然是另一个UIViewController)时,我遇到了一个问题。 如果我从AdminPanel导航到Products,则不会崩溃,因为我有一个从Products到AdminPanel的
推送操作。但是从AdminPanel到Cart,我没有任何
推送功能

下面是一张有bug的图片:

这是错误:“无法将“MyAppName.AdminPanelViewController”(0x10e878418)类型的值强制转换为“MyAppName.ProductsViewController”(0x10e877e00)

这是我的设计:

这是我的密码:

    // PRODUCTS VC
    class ProductsViewController: UIViewController{

var selectedProductsArray = [Product]()
    var priceForSelectedProductsArray = [Float]()

       // Func which is using GestureRecognition to access the Admin Panel when we press on User Avatar
        func accessToAdminPanel(){

            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ProductsViewController.adminImageTapped(gesture:)))

            userAvatarImageView.addGestureRecognizer(tapGesture)
        }

        // Function to open the AdminPanelViewController
        @objc func adminImageTapped(gesture: UIGestureRecognizer) {

            let storyBoard : UIStoryboard = UIStoryboard(name: Constants.nameOfMainSB, bundle:nil)
            let adminPanelVC = storyBoard.instantiateViewController(withIdentifier: Constants.adminPanelStoryboard) as! AdminPanelViewController
            self.navigationController?.pushViewController(adminPanelVC, animated: true)

        }


        // Func which will add the product into an array of products when the user press Add To Cart
        func didTapAddToCart(_ cell: ProductTableViewCell) {
            let indexPath = self.productsTableView.indexPath(for: cell)

            addProduct(at: indexPath!)
            selectedProductsArray.append(productsArray[(indexPath?.row)!]) // Append products for cart
            priceForSelectedProductsArray.append(productsArray[(indexPath?.row)!].price) // Append prices for selected products
        }

    }


    // CART VC
    class CartViewController: UIViewController {

 var productsInCartArray = [Product]()
    var productPricesArray = [Float]()

     // Append the selectedProducts into productsInCartArray using the TabBarController
        func fetchSelectedProducts() {

    // ------------------HERE IS CRASHING AT THIS LINE -----------------------
            productsInCartArray = ((self.tabBarController?.viewControllers![0] as! UINavigationController).topViewController as! ProductsViewController).selectedProductsArray
            productPricesArray = ((self.tabBarController?.viewControllers![0] as! UINavigationController).topViewController as! ProductsViewController).priceForSelectedProductsArray
            totalSum = productPricesArray.reduce(0, +)
        }

    }
如果你不能用这段代码找出哪里崩溃了,我可以给你git源代码的链接,因为我没有什么要隐藏的


如果您正在阅读本文,非常感谢您抽出宝贵的时间,我希望您能帮助我,因为我花了半天的时间试图找到解决方案来修复这个使我的应用程序崩溃的错误。

topViewController现在是管理员而非产品,因此您需要在索引0处获得VC,它是产品

productsInCartArray = ((self.tabBarController?.viewControllers![0] as! UINavigationController).viewControllers[0] as! ProductsViewController).selectedProductsArray

错误告诉您您正试图将
AdminPanelViewController
强制到
ProductsViewController
(在该行的
topViewController中作为!ProductsViewController
部分)。这是因为当您推到AdminPanelViewController时,它会移动到导航堆栈的顶部,替换您假设应该存在的ProductsViewController

短期内有许多方法可以处理此错误,例如迭代导航堆栈,而不只是抓取topViewController,如下所示:

guard let navController = self.tabBarController?.viewControllers![0] as? UINavigationController else {
    // handle error
    return
}
for controller in navController.viewControllers {
    if let productsController = controller as? ProductsViewController {
        // do work here
    }
}
但我认为更重要的是,你必须重新思考你是如何获取信息的。一般来说,您不应该在导航堆栈中行走来完成工作。在堆栈中导航时,最好在控制器之间传递数据


另外,您应该尽量避免使用
as
并应使用
作为?
替代,这将允许您捕获在应用程序崩溃的情况下角色转换无法工作的情况。我的个人目标是只使用
在IBOutlet声明中,而不是其他任何地方,但您的里程数可能会有所不同。

在哪里添加该行代码?我需要AdminPanel中的函数?您当前的代码不包含崩溃点所在的位置,请将代码附加到您转换为的位置!ProductsViewControllerBut在我的帖子里。我还添加了一条评论:“这里正在崩溃”