Sadi Hakan
Sadi Hakan

Reputation: 231

Perform segue click button from collection view inside table view

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

Answers (2)

Robert Dresler
Robert Dresler

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

Shivam
Shivam

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

Related Questions