Reputation: 1807
I have a general view controller with a button attached to the bottom and a container view above it. There is a table view embedded in the container view, that supports multiple selection. When 1 or more things have been selected in the tableview, I want the button to appear (slide up from bottom) and take the data selected in the tableview and use it to fire off a request from the general view controller. But my question is how do I get the data from that table view controller?
General
View Controller
| |
| |
|container|-----> table view controller
| |
| |
| |
|_________|
| btn |
that's a rough sketch of what I have going on. I'm using the container view so I can add the button and other UI elements freely to the overall view. If I have an array/list of things selected in the table view controller, how do I send it back to the General View Controller? Do I have to have the array/list in the General View Controller and some kind of a delegate in Table View Controller that takes the selected item and adds it into GVC?
Upvotes: 0
Views: 838
Reputation: 285
In addition to using the delegate pattern, Swift makes it easy to use closure callbacks for single callback use cases where a protocol may feel like a bit of overhead:
class SelectionViewController: UIViewController {
var itemsSelected: (([Item]) -> Void)!
...
tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
itemsSelected(itemsForSelectedRows)
}
...
private var itemsForSelectedRows: [Item] {
// Return the list of selected items based on e.g. tableView.indexPathsForSelectedRows
}
}
class GeneralViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let controller = segue.destination as? SelectionViewController {
// Note [weak self] to prevent a reference cycle between the two controllers
controller.itemSelected = { [weak self] items in
self?.fireOffRequestSomewhere(items)
}
}
}
}
Upvotes: 0
Reputation: 4592
Use the delegation pattern.
In your ViewController.swift
:
protocol MyTableDelegate {
func rowSelected()
}
class ViewController: UIViewController, MyTableDelegate {
@IBOutlet weak var container: UITableViewController!
var container: MyTable?
...
func rowSelected() {
// show my amazing button
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "myAmazingTable" {
self.container = (segue.destination as! MyTable)
self.container!.delegate = self
}
}
In your Table.swift
:
class MyTable: UITableViewController {
var delegate: MyTableDelegate?
func rowWasSelected() {
delegate!.rowSelected()
}
}
Upvotes: 1