1

I am trying to create a UITableView similar to the About section of the iOS settings. I have my initial table view, which I populate dynamically (already working), and which has disclosure indicators for each of its items. When I click on an item in this view, I tell the navigation controller to slide over to a static UITableView (pictured below). I instantiate the static table view from the storyboard using its ID, and before I transition to it, I'd like to fill it with dynamic values according to which item it's describing from the initial table view. Basically, how do I set the Right Detail portions of cells in a static table view in my code.?

The static UITableView.

The pseudocode I'm looking for goes something like this (exists inside the controller class for the initial table view):

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

  let customData: [String:String] = getDataForCell(atIndexPath: indexPath)
  let descriptionView = storyboard?.instantiateViewControllerWithIdentifier("keyDetails") as! KeyDetailsController

  descriptionView.getCell(forRow: 0, inSection: 0).rightDetail.text = customData["serverName"]! // changes "A Fake Server" to an actual server name

}
Sam Claus
  • 1,807
  • 23
  • 39
  • Just create `IBOutlet` references to those labels and then update the `text` property for those outlets. – Rob Sep 09 '16 at 18:58
  • @Rob I already tried that. I created a controller class for the static "About" table views and cast them to that, and filled it with IBOutlets for each of the details listed. However, the IBOutlets were always `nil` at runtime. – Sam Claus Sep 09 '16 at 19:01
  • @Rob I assume that was because this is not the way static table views are supposed to be used (it seems that they're only intended to be used with values set in the storyboard). – Sam Claus Sep 09 '16 at 19:02
  • That's because you're trying to use those outlets immediately after you instantiated the view controller, rather than waiting for the destination controller's view to be loaded (e.g. you can't reference the outlets until after `viewDidLoad` in that destination scene was called, which generally happens later, during the process of presenting/showing that scene). Also, as an aside, if you have `IBOutlet` references from the cell directly to the view controller, then you don't need to do that `getCell` stuff. If you want, you can, but it's more complicated than it needs to be. – Rob Sep 09 '16 at 19:05
  • @Rob Thanks! And yes, I originally had outlets such as `serverName` and called `descriptionView.serverName.text = `. I didn't think about the fact that the view might not have even been loaded. Is there anyway I can force the view to load one I obtain a reference from the storyboard? I would prefer to not get messy, and just handle table population right after I instantiate it. Also, If you write an answer instead of a comment, I'll choose it. – Sam Claus Sep 09 '16 at 19:12
  • @Rob I was typing before your new comment showed up for me. So you're saying that I implement some of the data source methods in the info table view controller and have them grab from class properties I set when I instantiated the controller? – Sam Claus Sep 09 '16 at 19:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/123019/discussion-between-rob-and-sam-claus). – Rob Sep 09 '16 at 19:22

1 Answers1

2

Just to summarize our discussion in chat: To update those labels, you just create IBOutlet reference to the labels.

The key issue here is that you're trying to update these outlets immediately after instantiating the view controller. But the outlets are not configured until the view is loaded, something that happens during the process of transitioning to the new scene. So you should:

  • Create String (or whatever) properties in the destination controller;

  • Populate these properties after the view controller is instantiated. Where yo do this depends upon how you're transitioning to the next scene:

    • If transitioning to the next scene programmatically (via showViewController, presentViewController or navigationController.pushViewController), then set these right after you call instantiateViewControllerWithIdentifier; or

    • If using a segue, set these String properties in prepareForSegue.

  • In viewDidLoad of the destination view controller, take these String properties and update the controls for which you have `IBOutlet references.

For more information, see Passing Data between View Controllers.

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044