1

Recently I have been making a app where you can create and quiz yourself on definitions or anything for that matter. I pass data to the next view after it the user hits the create button to make the title of the new notecard. The code I am using right now for that is:

override  func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

let DestViewController: Card1 = segue.destinationViewController as! Card1

DestViewController.Content = Notetitle.text!


self.saved = self.Notetitle.text!


}

All of that works but, it will only work if I have a segue between viewcontrollers. I need to be able to pass that data with out a segue because I want the user to be able to create as many notecards as they want and the way I am trying to do that now is by using this code to make a copy of the UIView and then put in the new data (a master view). The new view can only be create using an IBAction. The prepare for segue I cannot use in the IBAction because it is it's own override function.

This is the code I am using to make a the new view:

let newCard =
    self.storyboard!.instantiateViewControllerWithIdentifier("Main")

self.presentViewController(newCard, animated: true, completion:nil)

My hope is that I will be able to make a new view and then pass in the data pass in the data that the user just made to go on the notecard. (Hope this makes any sense at all)

MAIN TOPICS: -Create a new view and pass in new data Problem: Can pass data without a segue dont have one :/ -Be able to pass data between view controllers without a segue :)

I am new to all of this about 5 months. All of my code is in swift. Take it easy on me please. Feel free to ask me with any questions or comments. I have already posted a question on this but I didnt get an answer so have at it.

Thanks, Lucas Mazza

rmaddy
  • 298,130
  • 40
  • 468
  • 517
MazzaMan
  • 113
  • 7

1 Answers1

1

Don't use global variables unless you really need to. Making global static singleton's does not follow best practices. For more information read: What is so bad about singletons?

A better solution

You can use the protocol delegate pattern. I've actually written an article on this topic here:

https://www.codebeaulieu.com/36/Passing-data-with-the-protocol-delegate-pattern

You'll need a protocol that defines a function that will accept data. Then your other view controller will need to implement the delegate. If you need step-by-step details see the link provided above, alternatively you can simply download the project below and examine the code.

Download Working Example Project

Here's the code to make your protocol-delegate pattern work:

View Controller 1:

class ViewController: UIViewController, PresentedViewControllerDelegate {

    @IBOutlet weak var textOutlet: UILabel!
    @IBAction func doPresent(sender: AnyObject) {
        let pvc = storyboard?.instantiateViewControllerWithIdentifier("PresentedViewController") as! PresentedViewController

        pvc.data = "important data sent via delegate!"
        pvc.delegate = self
        self.presentViewController(pvc, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func acceptData(data: AnyObject!) {

        self.textOutlet.text = "\(data!)"

    }
}

View Controller 2:

import UIKit

// place the protocol in the view controller that is being presented
protocol PresentedViewControllerDelegate {
    func acceptData(data: AnyObject!)
}

class PresentedViewController: UIViewController {
    // create a variable that will recieve / send messages
    // between the view controllers.
    var delegate : PresentedViewControllerDelegate?
    // another data outlet
    var data : AnyObject?


    @IBOutlet weak var textFieldOutlet: UITextField!
    @IBAction func doDismiss(sender: AnyObject) {
        if textFieldOutlet.text != "" {
            self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        print("\(data!)")

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        if self.isBeingDismissed() {
            self.delegate?.acceptData(textFieldOutlet.text)
        }
    }
}
Community
  • 1
  • 1
Dan Beaulieu
  • 17,926
  • 15
  • 92
  • 126
  • I get error: undeclared type "PresentedViewControllerDelegate" any help – MazzaMan Dec 23 '15 at 01:07
  • did you declare the protocol at the top of your file (above your class)? as shown at the top of view controller 2 in my code snippet – Dan Beaulieu Dec 23 '15 at 01:08
  • I get these two errors: Type 'ViewController' does not conform to protocol 'PresentedViewControllerDelegate' and Use of unresolved identifier 'data' even though I have declared data in my class in the presentviewcontroller. I get both these errors in my viewcontroller. – MazzaMan Dec 23 '15 at 04:32
  • @MazzaMan have you downloaded my project files to see how my example works? You can see it in action and then compare it to your code. – Dan Beaulieu Dec 23 '15 at 04:34
  • @MazzaMan also, the error "ViewController" does not conform to protocol. You need to make sure the method "func acceptData(data: AnyObject!)" is defined in your view controller in order for it to conform – Dan Beaulieu Dec 23 '15 at 04:35
  • Thanks @Dan Beaulieu I appreciate your patience and I just needs some rest coding while tired is not a good idea. Made sure to give you the check! – MazzaMan Dec 23 '15 at 18:47
  • @MazzaMan no problem, thanks for accepting and I've given you an upvote. – Dan Beaulieu Dec 23 '15 at 19:34