Reputation: 11
I'm working on an app and I need to send data in an array from one view controller to another. I'm pulling a String from a label into a variable and appending it into the array.
var time:String = timeLabel.text!
timeArray.append(time)
print("add data")
I then have a prepareForSegue
function where I want to pass data from firstViewController
to SecondViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
let nvc = segue.destinationViewController as! SecondViewController
nvc.timeArray2 = timeArray
}
In my secondViewController, I have all of the necessary functions for a tableView
, but my tableView never populates with any data, as the timeArray2
is empty and will either result in a crash or in an empty tableView
.
override func viewWillAppear(animated: Bool)
{
scrambleTimeTableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return timeArray2.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = scrambleTimeTableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)
cell.textLabel?.text = timeArray2[indexPath.row]
cell.textLabel?.font = UIFont(name: "Arial", size: 18)
cell.textLabel?.textColor = UIColor.blueColor()
print("Populate tableview")
return cell
}
Anything I'm missing?
EDIT:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = scrambleTimeTableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)
cell.textLabel?.text = timeArray2[indexPath.row]
cell.textLabel?.font = UIFont(name: "Arial", size: 18)
cell.textLabel?.textColor = UIColor.blueColor()
print("Populate tableview")
return cell
}
I get a crash on cell.textLabel?.text = timeArray2[indexPath.row]
because the array in the secondViewController is empty. The error reads:
Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
The output says:
empty
[]
fatal error: Index out of range
(lldb)
I had it print the array and if it was full/empty, along with if the array was filling in the firstViewController, which looks like this:
add data
["01.12"]
add data
["01.12", "01.48"]
So I know that the 1st array is filling, and its not able to send any data to the 2nd controller.
Upvotes: 1
Views: 791
Reputation: 3347
Passing info between view controllers can be tricky, especially when one of them is a tableview. The timing of the events is kinda counterintuitive. To avoid problems, you shouldn't assume things load in any particular order.
In your specific case, it's possible tableView(tableView: UITableView, numberOfRowsInSection section: Int)
is being called before the segue happens (the API doesn't guarantee this won't happen, so we need to handle that case).
The fix: first, never use force-unwrapped optionals (the ! operator). Optionals exist for exactly this reason: if something is optional, you need to check if it's valid before you use it -- it's a "hint" that it's possible for the data not to be valid at some point in time.
Second: use a didSet
in your timeArray
to trigger your reloadData()
Something like this:
var timeArray: [MyTimeType] = [] {
didSet {
tableView.reloadData()
}
}
Also, your segue function should be more like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if let nvc = segue.destinationViewController as? SecondViewController {
nvc.timeArray2 = timeArray
}
}
The destinationViewController
may or may not be the one you expect -- you should always check.
Hope that helps!
Upvotes: 2