Search code examples
iosswiftuiviewcontrolleribaction

How to call a first view controller function from second view controller on a button tap in swift ?


I have a requirement where I have to call a first view controller function from second view controller on a button tap.

class FirstViewController: UIViewController {

    @IBAction func firstButtonPressed(_ sender: Any) {
    // Doing ABC
    }

@IBAction func showSecondVC_ sender: Any) {
        // showingSecondVC
        }

}

    class secondViewController: UIViewController {
@IBAction func SecondButtonPressed(_ sender: Any)
    // Dismiss second vc & call First View controller method so that it does ABC.
    }

My first question is can we initiate First VC IBAction directly from second VC ? Is it possible ?

I am thinking to do following

class FirstViewController: UIViewController {

    @IBAction func firstButtonPressed(_ sender: Any) {
    // call DoABC
    }

func DoABC {
// Doing ABC
}

}

    class secondViewController: UIViewController {
@IBAction func SecondButtonPressed(_ sender: Any)
    // Dismiss second vc 
// Call Firstvc.DoABC ?? How to do this ??
    }  

How to call the first vc method from the second vc ??


Solution

  • You have a few options here:

    1. Split out the logic, call the same code from each view controller
    2. Use a closure callback
    3. Use the delegate pattern as a method of calling back

    Option 1 - Split out the logic:

    class FirstViewController: UIViewController {
    
      let abcPerformer = ABCPerformer()
    
      @IBAction func firstButtonPressed(_ sender: Any) {
        abcPerformer.doABC()
      }
    
      @IBAction func showSecondVC_ sender: Any) {
        // showingSecondVC
      }
    
    }
    
    class SecondViewController: UIViewController {
    
        let abcPerformer = ABCPerformer()
    
        @IBAction func SecondButtonPressed(_ sender: Any) { 
          // Dismiss second vc & call First View controller method so that it does ABC.
          abcPerformer.doABC()
        }
    
    }
    
    struct ABCPerformer {
    
      func doABC() {
        // do ABC
      }
    
    }
    

    Option 2 - Create a callback:

    class FirstViewController: UIViewController {
    
      @IBAction func firstButtonPressed(_ sender: Any) {
        doABC()
      }
    
      @IBAction func showSecondVC_ sender: Any) {
        // showingSecondVC
        secondVC.doABC = doABC
      }
    
      func doABC() {
        // do ABC
      }
    
    }
    
    class SecondViewController: UIViewController {
    
        var doABC: (() -> Void)?
    
        @IBAction func SecondButtonPressed(_ sender: Any) { 
          // Dismiss second vc & call First View controller method so that it does ABC.
          doABC?()
        }
    
    }
    

    Option 3 - Use a delegate:

    protocol ABCProtocol {
      func doABC()
    }
    
    class FirstViewController: UIViewController, ABCProtocol {
    
      @IBAction func firstButtonPressed(_ sender: Any) {
        doABC()
      }
    
      @IBAction func showSecondVC_ sender: Any) {
        // showingSecondVC
        secondVC.delegate = self
      }
    
      func doABC() {
        // do ABC
      }
    
    }
    
    class SecondViewController: UIViewController {
    
        weak var delegate: ABCProtocol?
    
        @IBAction func SecondButtonPressed(_ sender: Any) { 
          // Dismiss second vc & call First View controller method so that it does ABC.
          delegate?.doABC()
        }
    
    }
    

    There is probably more options too, but these should give you enough choice to make a decision