Search code examples
swiftdelegatessegue

How do I pass an array without a segue?


I have a series of VCs. There is a restaurantMenuTableVC that is embedded in a navigationVC. When the user adds an item into the shoppingCartVC that is opened modally, I need to send the array of cart items to the paymentVC which needs to be pushed (not shown modally). So what I am doing is dismissing the shopping cart and trying to push the payment screen but nothing is working. Here is what I have tried:

Method 1 (using a simple delegate): I dismiss the shopping cart and then from the restaurantMenuVC segue to the paymentVC:

@IBAction func didTapNext(_ sender: UIButton) {

        dismiss(animated: true)
        delegate?.payNow()
}

And in the delegate function in menuVC I have this:

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let paymentViewController = segue.destination as? PaymentViewController {
                paymentViewController.cartItemArray = self.cartItemArray
            }
        }

Well all that happens is that the shopping cart modal is dismissed but paymentVC does not open.

Method 2: In the delegate function, I have this:

let paymentViewController = self.storyboard?.instantiateViewController(identifier: "PaymentViewController") as? PaymentViewController
        self.navigationController?.pushViewController(paymentViewController!, animated: true)

This works but I cannot pass the array because there is no segue.

I cannot simply segue from the shoppingCartVC to the paymentVC because it opens the paymentVC modally. I cannot push it either because then it gets pushed twice for some reason. It UX needs to close the shoppingCartVC and then transition to the paymentVC.

What do I do?


Solution

  • If you want to present a scene after dismissing another, use the completion handler of dismiss:

    dismiss(animated: true) {
        delegate?.payNow()
    }
    

    BTW, if you want to pass data when manually pushing, set the value after you instantiate the view controller, but before you push it:

    paymentViewController = storyboard!.instantiateViewController(identifier: "PaymentViewController") as! PaymentViewController
    paymentViewController.property = ...
    navigationController?.pushViewController(paymentViewController, animated: true)
    

    When you manually call pushViewController, the prepare(for:sender:) is not called.