Reputation: 433
Right now I am creating a table view cell from a nib file. I have a button in this nib file. I want this button to trigger a segue to a specific view controller on the storyboard.
Seems pretty straight forward, except this nib file is being used in many different tables on different view controllers throughout my app, and I want the button to link to the same destination view controller in every single instance. Furthermore, the destination view controller also contains a table with this nib file as a cell, meaning it will also need to link to itself.
For these reasons, I would love if there was a solution that contained this code to the UITableViewCell subclass for said nib file. (however I doubt this is possible.)
A good example of the functionality I want is Instagram. Think about how several different tabs on Instagram have tables with cells that look like this:
and no matter what tab you are in, clicking the username on the top left of this cell transitions you to the user view controller, even if you are already in the user view controller:
Upvotes: 0
Views: 90
Reputation: 3152
You can use a create a protocol that will return the required ViewController that you want to navigate to. You just need to make your custom cell conform to the protocol and return the required view controller or storyboard identifier. Once that is done in the didSelect
method you can try casting it as that protocol. If it succeeds push the required view controller. Check this code below where I'm using a storyboard identifier to get the required view controller
protocol CustomCellNavigator {
var identifier: String { get }
}
class YourViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var myTableView: UITableView!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourIdentifier", for: indexPath) as! CustomCell
cell.destinationStoryBoardIdentifier = "YourIdentifier"
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = myTableView.cellForRow(at: indexPath) as? CustomCellNavigator {
if let viewcontroller = storyboard?.instantiateViewController(withIdentifier: cell.identifier) {
navigationController?.pushViewController(viewcontroller, animated: true)
}
}
}
}
class CustomCell: UITableViewCell, CustomCellNavigator {
var identifier: String {
get { return destinationStoryBoardIdentifier }
}
// You can replace with whatever logic you want to use for
// finding the required viewcontroller
// I have just used a storyboard identifier here
var destinationStoryBoardIdentifier = "YourViewController"
}
Upvotes: 0
Reputation: 4855
here you can do as :
1) no need of tags to provide 2) get button location and perform task according to that 3) ProductStarImage //is my button name
Step 1:
//IBOutlets
@IBOutlet weak var CategoriesTableView: UITableView!
//TableCell identifier
let cellReuseIdentifier = "Cell"
var cell = CustomTableCellClass()
Step 2: in cellForRowAt of TableView
//setting cell data
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.CategoriesTableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! CustomTableCellClass
cell.layer.shadowColor = UIColor.gray.cgColor
cell.layer.shadowRadius = 2
//add a action to button
cell.ProductStarImage.addTarget(self, action: #selector(CategoriesVC.FavouriteButtonHandler(sender:)), for: .touchUpInside)
return cell
}
Step 2 : Button handler
//Favourite button Action Handler
@objc func FavouriteButtonHandler (sender: UIButton) {
//assign current cell to global cell declared //dequeue
cell = self.CategoriesTableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! CustomTableCellClass
//get CGPoint of button selected
let buttonPosition : CGPoint = sender.convert(CGPoint.zero, to: self.CategoriesTableView)
//get indexPath from CGPoint of Button
let indexPath : IndexPath = self.CategoriesTableView.indexPathForRow(at: buttonPosition)!
//Now assign selected cell indexPath to Cell declared globally
cell = self.CategoriesTableView.cellForRow(at: indexPath)! as! CustomTableCellClass
//here perform action required
like - cell.ProductStarImage //any action
self.CategoriesTableView.reloadRows(at: [indexPath], with: .none)
}
Upvotes: 1
Reputation: 1231
Use addTarget to your button.
put this code in cellForRowAt method of tableView.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_ID", for: indexPath) as? InstagramCell else { return }
cell.nasaBtn.addTarget(self, action: #selector(firstViewController.nasaBtnPressed(_:)), for: .touchUpInside)
return cell
}
@objc func nasaBtnPressed(_ sender: UIButton) {
performSegue(withIdentifier: "NASA_PROFILEID", sender: nil)
}
Upvotes: 0