Swift - Segue from Button Inside a Cell

Perform a segue using a button in a custom cell and passing on an object

In this case, I'm following these steps:

1) Add 'Your Edit Button' into your UITableViewCell and create IBOutlet.

class YourTableViewCell: UITableViewCell {
@IBOutlet weak var yourEditButton: UIButton!
}

2) In your cellForRowAtIndexPath method, assign button tag as index.

 cell.yourEditButton.tag = indexPath.row

3) Create IBAction in your View Controller. Open storyboard and connect "your edit button" with this IBAction function.

class YourViewController: UIViewController {

let selectedMedicine: Medicine? //your global Medicine variable

@IBAction func editButtonTapped(_sender: UIButton) {
//now you can access selected row via sender.tag

selectedMedicine = medicines[sender.tag]
preformSegue(withIdentifier: "showDetails", sender: nil)
}
}

Finally:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetails" {
let destination = segue.destination as! MedicineDetailTableViewController
destination.medicine = selectedMedicine
}
}

Performing a segue from a button within a custom UITableViewCell

Create a Protocol with the Method, that will be called by the CustomCell's Delegate, defined on your TableViewController

//Pass any objects, params you need to use on the 
//segue call to send to the next controller.

protocol MyCustomCellDelegator {
func callSegueFromCell(myData dataobject: AnyObject)
}

Now use the Protocol on your UITableViewController

class MyTableViewController : UITableViewController, MyCustomCellDelegator {

//The usual Defined methods by UIViewController and UITableViewController

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

//Set the CustomCell new Delegate
var cell = tableView.dequeueReusableCellWithIdentifier(customIdentifier) as MyCustomCell

cell.delagete = self

return cell

}

//MARK: - MyCustomCellDelegator Methods

func callSegueFromCell(myData dataobject: AnyObject) {
//try not to send self, just to avoid retain cycles(depends on how you handle the code on the next controller)
self.performSegueWithIdentifier("showComments", sender:dataobject )

}

}

Define the Delegate on your Custom Cell and the Call inside your New Button the Delegate Function.

class MyCustomCell : UITableViewCell {

var delegate:MyCustomCellDelegator!
@IBOutlet weak var myButton:UIButton

@IBAction func buttonPressed(sender:AnyObject){
var mydata = "Anydata you want to send to the next controller"
if(self.delegate != nil){ //Just to be safe.
self.delegate.callSegueFromCell(mydata)
}
}
}

Hopefully this can be clean and clear for you to understand and implement in your code.

Segue to detailed view controller using a button in a cell

It is obvious that you are getting that crash because with your button action you are calling performSegue(withIdentifier: "UsersProfile", sender: self) now with sender you are passing self means reference of current controller not the UICollectionViewCell what you need is get the indexPath of that cell and pass that and now in prepareForSegue cast the sender to IndexPath instead of UICollectionViewCell.

First replace your editButtonTapped with below one

@IBAction func editButtonTapped(_ sender: UIButton) -> Void {
print("Hello Edit Button")

let point = sender.superview?.convert(sender.center, to: self.tableView)
if let indexPath = self.tableView.indexPathForRow(at: point!) {
performSegue(withIdentifier: "UsersProfile", sender: indexPath)
}
}

Now in prepareForSegue for identifier UsersProfile cast the sender to IndexPath or simply replace your condition with my one.

if segue.identifier == "UsersProfile" {

if let indexPath = sender as? IndexPath{
let vc = segue.destination as! UsersProfileViewController
let post = self.posts[indexPath.row] as! [String: AnyObject]
let username = post["username"] as? String
let userpicuid = post["uid"] as? String
vc.username = username
vc.userpicuid = userpicuid
print(indexPath.row)
}
}

How to segue into a new view controller from button in table view cell

try

var profilePressed: ((UITableViewCell) -> Void)?

@IBAction func profileNamePressed(_ sender: Any) {
profilePressed?(self)
}

in your table view cell class, and this:

cell.profilePressed = { (cell) in
let profileVC = self.storyboard?.instantiateViewController(withIdentifier: "ProfileVC") as! ProfileVC
profileVC.initData(withPostedBy: message.postedBy)
self.presentDetail(profileVC)
}

in your cell for row at index path function

How to create a long press button in TableView Cell to segue

I found an easy yet unorthodox solution but works like a charm:

Place a second button into your TableView Cell, connect your segue, and set it to hidden. Then create your IBOutlet for it, which I named SegueButton:

@IBOutlet weak var LongPressButton: UIButton!
@IBOutlet weak var SegueButton: UIButton!

Now add to your awakeFromNib:

override func awakeFromNib() {
addLongPressGesture()
}

Lastly, add the long press button code:

@objc func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizer.State.began {
print("Segue was Successful")
SegueButton.sendActions(for: .touchUpInside)
}
}

func addLongPressGesture(){
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
longPress.minimumPressDuration = 0.75
self.LongPressButton.addGestureRecognizer(longPress)
}
}

How can i use uitableview cell for performing segue

Implement the UITableViewDelegate protocol method tableView(_:didSelectRowAt:) as below

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch sections[indexPath.row] {
case "Main Menu":
performSegue(with: "toMainMenu", sender: nil)
case "Settings":
performSegue(with: "toSettings", sender: nil)
case "Profile":
performSegue(with: "toProfile", sender: nil)
}
}

If you need to configure or pass some data to the destination controller, you can override the controller's prepare(for:sender:) method to get a reference, for example:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toMainMenu" {
let dvc = segue.destination as! MenuViewController
// now you have a reference
}
}

Swift UIbutton inside tableviewCell tp perform segue is not working

The issue is that in prepare(for:sender:) you are getting indexPath using indexPathForSelectedRow now if you directly click the button then cell with not selected what you need is to pass the indexPath of cell with performSegue(withIdentifier:sender:).

func someAction(sender:  UIButton) {
let point = sender.superview?.convert(sender.center, to: self.tableView)
if let indexPath = self.tableView.indexPathForRow(at: point!) {
//pass indexPath as sender with performSegue
self.performSegue(withIdentifier: "showDetail", sender: indexPath)
}
}

Now in prepare(for:sender:) cast the sender to indexPath and you all good to go.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = sender as? IndexPath
{
(segue.destination as! ViewController).number = numberArray[indexPath.row]
}
}
}

Note: It is batter if you ignored to use tag.



Related Topics



Leave a reply



Submit