Omar Gonzalez
Omar Gonzalez

Reputation: 1147

Unexpectedly found nil while unwrapping an Optional value while opening UIViewController

I'm doing a simple tableview app with swift, in which you open a new view controller programatically after clicking on a table row:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

//GLobals
@IBOutlet weak var table: UITableView!
//Table View Data

let cats :[String] = ["Gala","Vito","Odin","Ema"]

override func viewDidLoad() {
    super.viewDidLoad()

    table.delegate = self
    table.dataSource = self
}

// MARK:  UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return cats.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = table.dequeueReusableCellWithIdentifier("CustomTextCell", forIndexPath: indexPath) as! UITableViewCell

    let row = indexPath.row
    cell.textLabel?.text = cats[row]

    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)

    let row = indexPath.row
    let cat : String = cats[row];
    println(cat)

    //Save cat for detail view
    var defaults = NSUserDefaults.standardUserDefaults()
    defaults.setObject(cat, forKey: "cat")
    defaults.synchronize()


    let detail:Detail = Detail();
    self.presentViewController(detail, animated: true, completion: nil);
}
}

The code in the detail view is the following:

class Detail: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.whiteColor()

    let defeaults = NSUserDefaults.standardUserDefaults()

    let cat = defeaults.stringForKey("cat")

    var label = UILabel(frame: CGRectMake(0, 0, 200, 21))
    label.center = CGPointMake(160, 284)
    label.textAlignment = NSTextAlignment.Center
    label.text = cat

    self.view.addSubview(label)
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    let home:ViewController = ViewController()
    self.presentViewController(home, animated: true, completion: nil)
}

However when the app goes back to ViewController I'm having "unexpectedly found nil while unwrapping an Optional value "

the error

I have try some of the other answers to this problem including, warping with if == nil some of the values, but I still can't find what is the problem.

I'm assuming the UIViewController is not loading the UITableViewDelegate and UITableViewDataSource again, but I don't understand why... and how would you load them from another view anyway?

Upvotes: 1

Views: 492

Answers (2)

luk2302
luk2302

Reputation: 57114

Instead of

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    let home:ViewController = ViewController()
    self.presentViewController(home, animated: true, completion: nil)
}

you should probably do

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    self.dismissViewControllerAnimated(true, completion: nil)
}

Otherwise you create a new instance of the ViewController for which the tableView is not set, therefore nil, therefore crash.

Upvotes: 1

Nikita Leonov
Nikita Leonov

Reputation: 5694

You initialize ViewController in touchesBegan from the code as result table is nil in a newly allocated ViewController. While before you were initialized it from InterfaceBuilder and it was set through IBOutlet. So when you execute code in viewDidLoad application crashes as table is not available.

You can change code as following and it should work fine:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
  dismissViewControllerAnimated(true, completion: nil)
}

Upvotes: 3

Related Questions