UITableView vs UICollectionView Segue
This article describes the difference between a UITableView
segue from a UICollectionView
segue.
If you first learned the UITableView
segue you will be surpised because using the same method on a UICollectionView
produces a different result. It took me some Googling to find the solution.
The first section describes the UITableView
segue followed by the UICollectionView
segue.
UITableView Segue
In the UITableView
example we have a UITableViewController
named MyViewController with a segue to another UITableViewController
named MyDetailViewController. The segue identifier (1) is ShowHistoryDetail.
Before a segue is performed, you can set a property in the destination view controller via the instance method prepare(for:sender:)
.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowHistoryDetail" {
let controller = segue.destination as! MyDetailViewController
controller.item = sender as? Item
}
}
When a UITableView
row is tapped, the UITableViewDelegate
is informed via the tableView(didSelectRowAt:)
instance method. The item corresponding to the row is then sent to the destination view controller with the performSegue(withidentifier:sender:)
method.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var item = items[indexPath.row]
performSegue(withIdentifier: "ShowHistoryDetail", sender: item)
}
UICollectionView Segue
In the UICollectionView
example we have a UICollectionViewController
named MyViewController which will segue to a UITableViewController
named MomentDetailViewController. UICollectionView
contains a UICollectionViewCell
(1). The segue identifier (2) is MomentDetail.
This is where the UICollectionView
differs from the UITableView
. In a UICollectionView
, connecting a segue from the storyboard is enough to perform the segue. If you call performSegue
when the cell is selected, the segue is performed twice!
To set the destination view controller property to the corresponding selected cell, do it from the prepare(for:sender:)
like so:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MomentDetail" {
if let cell = sender as? UICollectionViewCell, let indexPath = self.collectionView.indexPath(for: cell){
let controller = segue.destination as! MomentDetailViewController
controller.item = items[indexPath.item]
}
}
}