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
How to Copy Skspritenode with Skphysicsbody
Identify Mkpointannotation in Mapview
How to Keep a Reference to Another Object in the Parameters of the Class
Swift: Overriding Typealias Inside Subclass
Countforfetchrequest in Swift 2.0
How to Have Arview and Arscnview Coexist
Swift; Delegate Embedded View Controller and Parent
Scntext Alignment Not Working in iOS
Swift 3 Init Method That Accepts JSON with Optional Parameters
Scenekit Physics Add Velocity in Local Space
Changing Nav Bar Item Programmatically in Swift
Prevent Redirect Response with Alamofire in Swift
Gmsplace Returns Invalid Coordinate (-180, -180), But Name and Place Id Are Correct
How to I Turn Off the Ambient Light in Scene Kit (With Swift)
Swiftui Widget iOS 14 Gradient Issue
iOS Charts Remove Decimal from Yvalues
How to Convert Data of Int16 Audio Samples to Array of Float Audio Samples