Reputation: 231
I have a table view with a collection view in my 2nd cell. And I have a button in collection view cell.
When a button from the collection view is clicked, i want to perform a segue to another view controller. And pass data. (But only button, not cell)
Upvotes: 1
Views: 1388
Reputation: 11150
I suppose you have subclass of UICollectionViewCell
with data inside so you can add action for your button to your cell
class YourCell: UICollectionViewCell {
...
var item: Item?
...
@IBAction func buttonPressed(_ sender: UIButton) {
}
...
}
now create delegate of your cell
protocol YourCellDelegate {
func buttonPressed(pass data: Item)
}
and create variable of delegate in your cell
class YourCell: UICollectionViewCell {
...
var delegate: YourCellDelegate?
...
}
then in button action call delegate method and pass data if you need to
@IBAction func buttonPressed(_ sender: UIButton) {
delegate?.buttonPressed(pass: item!)
}
Now implement YourCellDelegate
protocol to your UITableViewCell
and also declare what should happen when button is pressed. To achieve this, create delegate of your UITableViewCell
and
protocol TableViewCellDelegate {
func buttonInYourCellPressed(pass data: Item)
class TableViewCell: UITableViewCell, YourCellDelegate {
...
var delegate: TableViewCellDelegate?
...
func buttonPressed(pass data: Item) {
delegate?.buttonInYourCellPressed(pass data: date)
}
}
also in collection view data source method inside UITableViewCell
set delegate of cell as your TableViewCell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
...
cell.delegate = self
...
}
finally implement your TableViewCellDelegate
to your UIViewController
and declare what should happen when button in collection view is pressed
class ViewController: UIViewController, TableViewCellDelegate {
...
func buttonInYourCellPressed(pass data: Item) {
performSegue(withIdentifier: "identifier", sender: data)
}
}
At the end, set delegate of TableViewCell in UITableView
data source method cellForRowAt
as your ViewController
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.delegate = self
...
}
then in prepare(for segue:
in your ViewController you can just assign property of destination ViewController to downcasted sender
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "identifier" {
let destinationVC = segue.destination as! SecondViewController
destinationVC.selectedItem = sender as! Item
}
}
Upvotes: 2
Reputation: 51
If you have created cells in storyboard itself, then you can directly create @IBAction func in your main ViewController
OR
If you have created xib, then try this way
You can do it in many ways, but i prefer doing it from Notification.
Try this
First of all you have to add an observer in your main controller from where you want to perform segue. just like this one :
NotificationCenter.default.addObserver(self, selector: #selector(self.testFunc(notification:)), name: Notification.Name("navigateToController"), object: nil)
Here is the code for your main class :
class YourMainViewController : UIViewController {
@IBOutlet weak var tableView : UITableView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.testFunc(notification:)), name: Notification.Name("navigateToController"), object: nil)
}
@objc func testFunc(notification:Notification) {
let object = notification.object as! YourObjectType /// For ex : [String], Int, CustomModel, Any etc..
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as! YourViewController
viewController.object = object
self.navigationController?.pushViewController(viewController, animated: true)
}
}
Here is the code for your table view cell class :
class yourTableViewCell: UITableViewCell {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "reuseIdentifier", for: indexPath) as! YourCollectionCell
cell.yourCellButton.addTarget(self, action: #selector(self.actionCellButton()), for: .touchUpInside)
return cell
}
@objc func actionCellButton() {
let myArr = ["1","2","3"]
NotificationCenter.default.post(name: Notification.Name("navigateToController"), object: myArr)
}
}
When you will click your button, actionCellButton() function will be called and from here you can pass data into notification object.
Just after the actionCellButton() function is called, testFunc() will be called and there you will receive your data which you passed in actionCellButton() function and code will be executed.
Upvotes: 0