Reputation: 691
I have a UIViewController with a segmented control element. Beneath this I have two overlapping container views that automatically create there own respective views in the storyboard. I have no problem linking these views up and presenting each view respective of the segmented control that is selected.
My problem lies when i try to implement a table view inside one of the container views and pass data to fill the view. To break this down lets say i have 3 View Controllers.
vc1 is of type UITableViewController : holds a table of categories.
vc2 is of type UIViewController: holds the segmented control and the two overlapping container views.
vc3 is of type UIViewController: is one of the container views that has a UITableView (that i have dragged in from the storyboard). This table displays a list of items in the category that was selected via the cell from vc1.
Normally i would be able to populate vc3 with the appropriate data to display the list of items for the table by simply using the prepareForSegue method in vc1 but since an extra ViewController is between these two ViewControllers I haven't been able to accomplish the same result.
The overall objective is to populate the tableView in vc3 with the appropriate data from the selected cell in vc1.
Segmented view controller is VC2 - in the example i referred to a category. In the code is actually a Trip that holds destinations. So thing that the category is a trip. The items within a category as the destinations within the trip (i.e. destinations are what is populating the table in vc3)
import UIKit
class SegmentedViewController: UIViewController {
var trip: Trip!
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var itineraryContainer: UIView!
@IBOutlet weak var plannerContainer: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = trip.tripName
itineraryContainer.hidden = true
//Setting the initial container to be viewed to match the segmentedcontrol
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func segmentedControlAction(sender: UISegmentedControl) {
switch segmentedControl.selectedSegmentIndex {
case 0:
plannerContainer.hidden = false
itineraryContainer.hidden = true
break
case 1:
plannerContainer.hidden = true
itineraryContainer.hidden = false
break
default:
break
}
}
}
Planner View Controller (Container
import UIKit
class PlannerViewController: UIViewController, UITableViewDataSource {
var trip: Trip!
var valueToAppend: String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return trip.destinations.count
}
private struct Storyboard {
static let CellReuseIdentifier = "Destination"
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Storyboard.CellReuseIdentifier, forIndexPath: indexPath)
//configure cell
cell.textLabel?.text = trip.destinations[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated:true);
}
}
Upvotes: 2
Views: 3181
Reputation: 691
After much more research and documentation reading I have solved my problem. Below are the steps to my problem for anyone who may come across a similar problem.
1.set the container scenes embed segue identifier
2.create an instance of your container view in the main VC (VC2 for this problem)
3.in the main VC (in my case VC 2) use the prepare for segue method to set the instance created in VC2.
4.set any variables that may need setting
5.make sure you create an IB outlet from the table view thats in the container scene to your code and set this as the datasource.
Upvotes: 1
Reputation: 9362
We solved the same situation in our app using a delegate protocol. It would look something like this in your situation:
Define a delegate protocol.
protocol CategorySelectionDelegate: class {
func categorySelected(category: String)
}
Define a delegate variable in your category view controller (vc1).
var categorySelectionDelegate: CategorySelectionDelegate?
In your category view controller (vc1), when the table row is selected, fire the delegate, passing the category name.
//get the category name from your model, based on the row selected...
//call the delegate, passing the category name
categorySelectionDelegate?.categorySelected(category)
Add the protocol to your main controller (vc2).
class vc2: UIViewController, CategorySelectionDelegate
In your main view controller (vc2), set it as the delegate for your category view controller (vc1).
vc1.categorySelectionDelegate = self
Implement the protocol in your main controller.
func categorySelected(category: String) {
//display the items for this category in vc3
}
Upvotes: 2