Karen
Karen

Reputation: 169

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 ??

Upvotes: 1

Views: 1543

Answers (4)

Oliver Atkinson
Oliver Atkinson

Reputation: 8029

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

Upvotes: 4

Ash
Ash

Reputation: 5712

To present your second view controller from First, You can use push or present transition.

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


//presenting VC 
let secondVC = SecondViewController() //change this to your class name
self.presentViewController(secondVC, animated: true, completion: nil)


//for push :
navigationController?.pushViewController(SecondViewController, animated: true)

}

You can use pop/dismiss VC accordingly in your second view to get back first view.

class secondViewController: UIViewController {

    @IBAction func SecondButtonPressed(_ sender: Any)
        // Dismiss second vc  // Call Firstvc.DoABC ?? How to do this ??
        //if you used Present in first step then use dismiss 
        self.dismissViewControllerAnimated(false, completion: nil)

    //if you used push in first step then use pop
        self.navigationController?.popViewController(animated: true) }

Upvotes: 0

Yogesh Dalavi
Yogesh Dalavi

Reputation: 73

You can Use custom delegate for that Like below and add function "presentPage" wherever you want to call.

protocol MainDelegate {
func  presentPage(page : Int)

}

Upvotes: 0

ghostatron
ghostatron

Reputation: 2650

  1. Create a protocol, say, SecondViewControllerDelegate.
  2. Add a method signature to that protocol, something like secondViewControllerDidPressButton.
  3. Add a var to secondViewController: var delegate: SecondViewControllerDelegate
  4. Update firstViewController to implement that protocol.
  5. In prepareForSegue of firstViewController, assign firstViewController as the delegate for the secondViewController that is about to be presented.
  6. Update secondViewController to call self.delegate.secondViewControllerDidPressButton when the button is pressed.

Upvotes: 0

Related Questions