0

I have 2 view controllers and a swift file. I wish to pass the data from one view controller to the other without using segue or presenting the other view controller.

View controller:

import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

var questions:[Question] = []

var sub = ""
var send = ""
var det = ""

@IBOutlet weak var questionsender: UISegmentedControl!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
    super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.tableView.reloadData()
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return questions.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 50
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "forumcell", for: indexPath) as! ForumTableViewCell
    cell.questionsubject.text = questions[indexPath.row].subject
    cell.sender.text = questions[indexPath.row].sender
    return cell
}


}

Swift file:

import Foundation
class Question
{
var subject = ""
var descript = ""
var sender = ""
init(subject : String, descrip: String,sender : String)
{
    self.sender=sender
    self.descript=descrip
    self.subject=subject
}
}

Second view controller:

import UIKit

class AddVC: UIViewController,UITextFieldDelegate {
var qsender = ""
var subject = ""
var details = ""

@IBAction func postBttn(_ sender: Any) {
    if questiondetails.text == "" || question_sender.text == "" || question_subject.text == ""
    {
        let alert = UIAlertController(title: "Invalid!", message: "One of the fields has not been entered", preferredStyle: .alert)

        let bttn = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
        alert.addAction(bttn)

    }
    else
    {
        qsender = question_sender.text
        subject = question_subject.text
        details = questiondetails.text
        let q=Question(subject: subject, descrip: details, sender: qsender)
        let v = ViewController()
        v.send = qsender
        v.sub = subject
        v.det = details
        dismiss(animated: true, completion: nil)
    }
}
@IBAction func closeBttn(_ sender: Any) {
    dismiss(animated: true, completion: nil)
}

@IBOutlet weak var question_subject: UITextView!
@IBOutlet weak var question_sender: UITextView!
@IBOutlet weak var closeBttn: UIButton!

@IBOutlet weak var questiondetails: UITextView!
override func viewDidLoad() {
    super.viewDidLoad()
    question_subject.placeholderText="Sender"
    question_subject.placeholderText="Subject"
    questiondetails.placeholderText="Description"
    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(swiped(_ :)))
    swipeDown.direction = .down
    self.view.addGestureRecognizer(swipeDown)

}
func swiped(_ gesture:UISwipeGestureRecognizer)
{
    dismiss(animated: true, completion: nil)
}
}

The object v I created for View Controller cannot update the data members through the AddVC class.

  • How are the 2 view controllers related? Does one segue into the other? And is there an order in which they are presented to the user? – Brian Sep 02 '17 at 07:37
  • Not 100% sure why those two viewControllers shouldn't be connected to each other, but you can always use `CoreData` to store and retrieve necessary data. – sCha Sep 02 '17 at 07:40
  • the values will be given by the user. I am developing a forum so the data entered must go to the server. – Pranav Karnani Sep 02 '17 at 07:43
  • Yes, AddVC is connected to ViewController via a segue which is being presented modally. Where, View Controller is the initial View Controller and AddVC is being presented – Pranav Karnani Sep 02 '17 at 07:43
  • Use `prpareForSegue` method to pass data. Please check this link: https://stackoverflow.com/questions/7864371/how-to-pass-prepareforsegue-an-object – Amit Sep 02 '17 at 07:45
  • Fine, in that case you should pass a reference to AddVC. I will post my answer below – Brian Sep 02 '17 at 07:45
  • @Brian tried that... did not work – Pranav Karnani Sep 02 '17 at 07:47

2 Answers2

0

Add this line to ViewController:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    static let viewControllerSegueIdentifier: String = "ViewController"

Make sure that the viewControllerSegueIdentifier string matches your segue identifier.

Then make these edits to AddVC:

@IBAction func postBttn(_ sender: Any) {
        if questiondetails.text == "" || question_sender.text == "" || question_subject.text == ""
        {
            let alert = UIAlertController(title: "Invalid!", message: "One of the fields has not been entered", preferredStyle: .alert)

            let bttn = UIAlertAction(title: "Ok", style: .cancel, handler: nil)
            alert.addAction(bttn)

        }
        else
        {
            qsender = question_sender.text
            subject = question_subject.text
            details = questiondetails.text
            dismiss(animated: true, completion: {
                goToAddScreen(segueIdentifier: ViewController.viewControllerSegueIdentifier)
            })
        }
}

Then add these 2 methods:

func goToAddScreen(segueIdentifier: String) {
        performSegue(withIdentifier: segueIdentifier, sender: self)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == ViewController.viewControllerSegueIdentifier {
            guard let controller = segue.destination as? ViewController else {
                return
            }
            let q=Question(subject: subject, descrip: details, sender: qsender)
            controller.questions.append(q)
        }
}
Brian
  • 573
  • 4
  • 8
0

in ViewController:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let destination = segue.destination as! AddVC
    destination.callbackFromAddVC = { stringData in
        // use stringData
    }
}

in AddVC:

var callbackFromAddVC: ((String) -> Void)? = nil

func swiped(_ gesture:UISwipeGestureRecognizer)
{
    self.callbackFromAddVC?("myStringData that needs to be transferred")
    dismiss(animated: true, completion: nil)

    self.callbackFromAddVC = nil
}
sCha
  • 1,454
  • 1
  • 12
  • 22