Reputation: 1147
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 "
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
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
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