Reputation: 33293
I am a newbie in swift and I smell a bad code in the following logic
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dest = segue.destination as? VC1,
let index = collectionView?.indexPathsForSelectedItems?.first{
dest.selection = self.cellLabels[index.row]
}
if let dest2 = segue.destination as? VC2,
let index2 = collectionView?.indexPathsForSelectedItems?.first{
dest2.selection = self.cellLabels[index2.row]
}
if let dest3 = segue.destination as? VC3,
let index3 = collectionView?.indexPathsForSelectedItems?.first{
dest3.selection = self.cellLabels[index3.row]
}
}
Essentially, I have multiple view controllers which I am trying to reach to depending on which Cell is tapped to.
Why I feel this is bad code is because there is a lot of code repeation. Is there a better way to structure this?
Upvotes: 9
Views: 1386
Reputation: 438307
I'd define protocol:
protocol YourProtocolName: class {
var selection: String? { get set } // obviously, use whatever type that is appropriate in your case
}
Have your three view controller classes conform to that protocol, e.g.:
class VC1: UIViewController, YourProtocolName {
var selection: String?
...
}
And then:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dest = segue.destination as? YourProtocolName,
let index = collectionView?.indexPathsForSelectedItems?.first {
dest.selection = cellLabels[index.row]
}
}
Upvotes: 17
Reputation: 96
I would do it using parent class for all three ViewController classes and place the shared variables in the parent class. e.g.
class ParentViewControllerClass: UIViewController{
var selection: Int?
}
class VC1: ParentViewControllerClass{
}
class VC2: ParentViewControllerClass{
}
class VC3: ParentViewControllerClass{
}
and then you should be able to assign value once. Like:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dest = segue.destination as? ParentViewControllerClass,
let index = collectionView?.indexPathsForSelectedItems?.first {
dest.selection = index
}
This way no matter which of three child view controllers is called the statement will be satisfied
Upvotes: 2
Reputation: 3373
guard let index = collectionView?.indexPathsForSelectedItems?.first else { return }
switch segue.destination {
case let dest1 as VC1: dest1.selection = cellLabels[index.row]
case let dest2 as VC2: dest2.selection = cellLabels[index.row]
case let dest3 as VC3: dest3.selection = cellLabels[index.row]
}
Upvotes: 4
Reputation: 132
Try this:
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "segueIdentifier", sender: collectionView.cellForItem(at: indexPath))
}
Upvotes: 1