1

I'm getting the error:

Fatal error: unexpectedly found nil while unwrapping an Optional value

whenever I try adding text to a text view (bottomTextView) outside of my view controller. My text view is linked to my main view controller. I have another class called Checkbox (subclass of UIButton) that tries to add text to the text view using:

var main_vc = ViewController()
main_vc.bottomTextView.insertText("Checked")

However, I have no problem using the following inside my view controller:

bottomTextView.insertText("Checked")

I can't figure out why this is and how to fix it. Thanks!

EDIT:

My Checkbox class is a subclass of UIButton that has a method that is called whenever a checkbox is clicked. When that checkbox is clicked I want to add text to the text view inside my main view controller.

Brejuro
  • 3,421
  • 8
  • 34
  • 61

3 Answers3

2

You do not have view initialized. My guess is you are creating if from a nib file and that is why you need to initialize it like this

var main_vc = ViewController(nibName: "ViewController", bundle: nil)

When you try to access is without the view, the IBOutlets are nil since they are not connected to anything. That is why you are getting that error.

The second thing works because all of the methods exist in your ViewController object but there is no view to control it.

If you have used the Storyboard to create the file, you would first need to set an identifier for that ViewController like this

enter image description here

And then create your ViewController like this

let storyboard = UIStoryboard(name: "Main", bundle: nil) // Or what ever your storyboard file name is
let main_vc = storyboard.instantiateViewControllerWithIdentifier("PublishView") as! ViewController // What you name your view controller
Stefan Salatic
  • 4,513
  • 3
  • 22
  • 30
  • Thanks for the response! This didn't seem to do the trick although it may be because I am unfamiliar of what a nib file is. – Brejuro May 04 '15 at 13:54
  • Where did you create your interface? Is the file called `something.storyboard` or `something.xib`? If it is in storyboard then you need to set identifier, and initialize it in a different way. Let me know if that is the case and I will fill in the answer. – Stefan Salatic May 04 '15 at 13:55
  • I created it in a storyboard – Brejuro May 04 '15 at 13:56
  • Thanks! However, similar to the other answer posted here I am getting an error `Checkbox.type does not have a member named storyboard` on the line `let main_vc = storyboard.instantiateViewControllerWithIdentifier("PublishView") as! ViewController` which is weird because it's the line right before it. – Brejuro May 04 '15 at 14:01
  • Hm, still get the same error. Someone mentioned how I may not be using MVC right? – Brejuro May 04 '15 at 14:13
  • If you are using Storyboards you are already using MVC. What you might be missing is the `Class` field from the image in the answer. You need to set it as your ViewController, the one with the IBOutlets for the controls. – Stefan Salatic May 04 '15 at 14:15
  • Not necessarily, you can still break the MVC design pattern if you're using Storyboards - having a view store information about your model, for example. – ABakerSmith May 04 '15 at 14:17
  • This link is a screen capture of what my storyboard looks like http://gyazo.com/75621cad651e3eb06d6b675c592b473a – Brejuro May 04 '15 at 14:19
1

If you are using Storyboard then;

var storyboard = UIStoryboard(name: "Main", bundle: nil)
var main_vc = storyboard.instantiateViewControllerWithIdentifier("ViewControllerIdentifier") as! ViewController
main_vc.bottomTextView.insertText("Checked")
ridvankucuk
  • 2,407
  • 1
  • 23
  • 41
  • Thanks for the response! This line `var main_vc = storyboard.instantiateViewControllerWithIdentifier("ViewControllerIdentifier") as! ViewController` is giving me the error `Checkbox.type does not have a member named storyboard` even it's right in the line before – Brejuro May 04 '15 at 13:55
  • If your class is a subclass of UIViewController, that piece of code should work. And be sure that in your Storyboard, you should add Storyboard ID for your View Controller. – ridvankucuk May 04 '15 at 14:02
  • My class is a subclass of UIButton, am I doing something glaringly wrong? My apologies I am new to this. I added more info in my problem – Brejuro May 04 '15 at 14:03
1

I suspect your problem is you're trying to access bottomTextView, from another view controller, before you've presented the view controller (with a segue for example). In that case none of your ViewController's IBOutlets have been set and so you're getting that error.

I think you're thinking about this in the wrong way though - a view controller shouldn't directly edit another view controller's view. Instead, you could set the text, that should appear in bottomTextView, in prepareForSegue. For example, say this was your ViewController class:

class ViewController : UIViewController {
    var yourText: String = ""
    @IBOutlet var bottomTextView: UITextView!

    override func viewDidLoad() {
        // In viewDidLoad all the outlets have been set so you won't get any errors
        // setting the text.
        bottomTextView.text = yourText
    }
}

And this was another view controller you wanted to move from, to an instance of ViewController:

class AnotherViewControler : UIViewController{
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let vc = segue.destinationViewController as? ViewController 
           where segue.identifier == "YourSegueID" {

            vc.yourText = "SomeText"
        }
    }
}

For more information on passing data between view controllers, have a look at this question: How do you share data between view controllers and other objects in Swift?

Community
  • 1
  • 1
ABakerSmith
  • 22,759
  • 9
  • 68
  • 78
  • I'm trying to access bottomTextView from another class called Checkbox which is a subclass of UIButton. I added more info to my problem above. Thanks for the reply! – Brejuro May 04 '15 at 14:07
  • It sounds me like you're not following the MVC design pattern. I would really recommend looking at the MVC lectures in this: https://itunes.apple.com/gb/course/developing-ios-8-apps-swift/id961180099 – ABakerSmith May 04 '15 at 14:09
  • Thanks for the resource. Do you think you could give me an idea of how I could accomplish the same thing using MVC? I'm familiar with what it means but I'm not very experienced with it. – Brejuro May 04 '15 at 14:11
  • With Model-View-Controller design pattern, you wouldn't use a view (your button) to directly talk to another Controller (`ViewController`). Instead, the button would send a message to the controller, which would then relay the information to another Controller. That's only a small part of MVC though and I would recommend looking at those lectures as they'll explain it in much more detail. – ABakerSmith May 04 '15 at 14:15
  • Thanks a lot! I'm wondering why I decided to have a separate class and not just have all that logic for those buttons in my view controller. I moved it all there and it works now. I'm going to check out those lectures. – Brejuro May 04 '15 at 14:27
  • 1
    Awesome, I'm glad I could help! Good luck with whatever you're working on! – ABakerSmith May 04 '15 at 14:28