iosswiftnavigationcontroller

Swift Navigate from third ViewController to the first ViewController


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
    let vc = storyboard?.instantiateViewController(identifier: 
    "PersonViewController") as? PersonViewController               
    
    vc?.names = persons[indexPath.row].emer!
    vc?.lastnames = persons[indexPath.row].mbiemer!
    vc?.delegate = self
    PersonViewController.indexes = indexPath.row 
    self.navigationController?.pushViewController(vc!, animated: true)

}`

I have a situations like this:

First ViewController is a collectionView, the second is a viewcontroller which is allowed to add new Person when I tap a button and works perfectly. I have used delegates and Core Data for local memory.

Also the second ViewController has another button to edit person. When I press button a new viewController appears with extension UIAdaptivePresentationControllerDelegate. This viewcontroller consists of 2 buttons and 2 textfields. So when I want to press save button I want to go to the first viewcontroller (collectionview list) and when to press cancel to go back to the second viewcontroller.

Viewcontrollers are created with pushViewController method.

image

Please anyone help what should I use?

then in PersonViewController I call this inside button edit.

@objc func editCell(){
    let vc = storyboard?.instantiateViewController(identifier: 
    "ModalPresentationViewController") as? 
     ModalPresentationViewController

     navigationController?.pushViewController(vc!, animated: true)
    
}

Now the code in the las ViewController which is ModalViewController

@objc func savePerson(){
    if editNameTextfield.text == "" || editlastNameTextfield.text == ""{
        self.errorLbl.alpha = 1
    }
    else{
        let vc = ViewController()
        guard let textName = editNameTextfield.text else{
            return
        }
        guard let textLastName = editlastNameTextfield.text else{
            return
        }

        let index = PersonViewController.indexes
        DispatchQueue.main.async {[self] in
            if editDelegate != nil{
                self.editDelegate!.editPerson(editedName: textName, editedLastname: textLastName, index: index)
            }
        }
//            What should I call here??
       
    }
}

Solution

  • You can use something like:

    func popTo(_ type: AnyClass) {
        guard let controllers = navigationController?.viewControllers else {return}
        
        for controller in controllers {
            if controller.classForCoder == type {
                navigationController?.popToViewController(controller, animated: true)
                break
            }
        }
    }
    

    And invoke the function depending on the condition as:

    popTo(A.classForCoder())
    

    EDIT: Above solution works only if ViewControllers B and C presented via a navigation controller and are in the same navigation stack.

    Since you present the ViewController C modally, below answer should work:

    Make these changes to your ViewController B that is presenting C:

    class B: UIViewController, PresenterDelegate {
    // some functions
    
        func popToPrevious() {
            navigationController.popViewController(animated: false)
        }
    
        @objc func editCell(){
            let vc = storyboard?.instantiateViewController(identifier: 
            "ModalPresentationViewController") as? 
             ModalPresentationViewController
            vc.presenterDelegate = self
    
            present(vc, animated: true, completion: nil)
    
        }
    }
    

    And in your ViewController C:

    class C {
        var presenterDelegate: PresenterDelegate? = nil
    
        //
    
        @objc func savePerson(){
            //
            //
            dismiss(animated: true, completion: {
                self.presenterDelegate?.popToPrevious()
            })
        }
    }
    

    Also add PresenterDelegate protocol to a new file or below ViewControllers B or C

    protocol PresenterDelegate {
        func popToPrevious()
    }