Delegates: Pass Data Without Segue

Passing Data between View Controllers without segue

If its a small data like some string or variable you can use UserDefault or pass data using that class variable like vc2.data = data
How to use UserDefaults How to use UserDefaults in swift?

If its more like table or number of user list you can use plist store in your bundle at can retrieve from any view controller
using Plist How do I get a plist as a Dictionary in Swift?

if two controller are some how connected you can use delegates.
delegats:- Delegates in swift?

You can also use notifications if you are not sure when data will be available/ or send base on some action, or send if something is trigged.

Pass data using Notifications How to pass data using NotificationCentre in swift 3.0 and NSNotificationCenter in swift 2.0?

Passing Data with without Segue from Container View to MainVC

Delegate pattern should help you. First of all you need the delegate protocol:

protocol SelectSoundVCDelegate {
func didSelectTrackNumber(_ trackNumber: Int)
}

with func that accept the trackNumber value. Next, you need to create delegate property in SelectSoundVC:

class SelectSoundVC: UIViewController {

weak var delegate: SelectSoundVCDelegate?
var trackNumber: Int!

@IBAction func winterSoundBut(_ sender: UIButton) {
trackNumber = 1
delegate?.didSelectTrackNumber(trackNumber)
}

}

that will be call the didSelectTrackNumber in @IBAction. Note that delegate property should be weak to avoid reference cycles. The last step, in MainVC you should set delegate property of SelectSoundVC:

selectSoundVC.delegate = self  

This part is little bit tricky, because you need the instance of SelectSoundVC to set the delegate. You can set it in prepareFoSegue method, for example:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let viewController = segue.destination as? SelectSoundVC, segue.identifier == "SelectSoundVC" {
viewController.delegate = self
}
}

Swift delegate beetween two VC without segue

You need to create one more protocol in your SecondViewController to Pass that delegate from ThirdViewController to FirstViewController.

FirstViewController:

import UIKit

class ViewController: UIViewController, DataSentDelegate, dataSentDelegate {

@IBOutlet weak var imagefromThirdVC: UIImageView!

var thirdVCImage: UIImage!

override func viewDidLoad() {
super.viewDidLoad()
}

@IBAction func buttonTapped(_ sender: Any) {
let vc = storyboard?.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}

func goToThirdVC() {
let vc = storyboard?.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}

func recievePhoto(data: UIImage) {
thirdVCImage = data
imagefromThirdVC.image = thirdVCImage
}
}

SecondViewController:

import UIKit

protocol dataSentDelegate {
func goToThirdVC()
}

class ViewController2: UIViewController {

@IBOutlet weak var passingImage: UIImageView!

var delegate: dataSentDelegate? = nil

var images: UIImage!

override func viewDidLoad() {
super.viewDidLoad()

images = UIImage(named: "screen")
}

@IBAction func actionButton(_ sender: Any) {
self.delegate?.goToThirdVC()
}

}

ThirdViewController:

import UIKit

protocol DataSentDelegate {
func recievePhoto(data: UIImage)
}

class ViewController3: UIViewController {

var delegate: DataSentDelegate? = nil

@IBOutlet weak var passedImageView: UIImageView!

var passedImage: UIImage!

override func viewDidLoad() {
super.viewDidLoad()

passedImage = UIImage(named: "screen")
passedImageView.image = passedImage
}

@IBAction func action(_ sender: Any) {

let data = passedImageView.image
delegate?.recievePhoto(data: data!)
// delegate?.goToFirstVC()

guard let viewControllers = self.navigationController?.viewControllers else {
return
}

for firstViewController in viewControllers {
if firstViewController is ViewController {
self.navigationController?.popToViewController(firstViewController, animated: true)
break
}
}

}

}

Pass data before popViewController without segue and storyboard

Use these links to understand exactly how to use Protocols in swift:

  • Passing data between two ViewControllers (delegate) - Swift

  • Passing Data between View Controllers

You have to implement below line of code in first view controller :-

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSecondViewController" {
let secondViewController = segue.destination as! SecondViewController
secondViewController.delegate = self
}
}

Pass data between view controllers WITHOUT segues

You can create a Segue not bounded to a button by ctrl+drag from the first controller to the second one (don't forget to give this segue and identifier).

Next In the IBAction of the button (set via Interface Builder or via addTarget:self action:forControlEvents: ) you can call the [self performSegueWithIdentifier:@"YourSegueIdentifier" sender:button];

You can pass the data to the second controller, as usual, in - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

swift delegate beetween two view controller without segue

Typically you set a new view controller's delegate property in prepareForSegue:. You said you're not using a segue, so you'll need to instantiate the second view controller and present it somehow. You can do this by doing something like:

let storyboard = UIStoryboard(name: "AStoryboardName", bundle: nil)
let secondVC = storyboard.instantiateViewControllerWithIdentifier(anIdentifier) as! targetViewController
secondVC.delegate = self
presentViewController(secondVC, animated: true, completion: nil)

You have a testDelegate() method in both view controllers, but you only want it in the first view controller. Then your second view controller can call delegate?.testDelegate() at the appropriate time.

Finally, you typically want to make delegate properties weak, so I would recommend changing var delegate : testProtocol? to weak var delegate: testProtocol?

I would read up on delegation. Here is a relatively simple 5 step process to delegation that may help you:

Delegation in 5 Steps:

object A is the delegate for object B, and object B will send out the messages:

  1. Define a delegate protocol for object B.
  2. Give object B an optional delegate variable. This variable should be weak.
  3. Make object B send messages to its delegate when something interesting happens, such as the user pressing the Cancel or Done buttons, or when it needs a piece of information.
  4. Make object A conform to the delegate protocol. It should put the name of the protocol in its class line and implement the methods from the protocol.
  5. Tell object B that object A is now its delegate (in prepareForSegue(sender)).


Related Topics



Leave a reply



Submit