Swift - Segue from Button inside a cell - swift

i have a custom cell attached to TableViewCell class, and i have a button inside that custom cell, i want whey i press the button it segues to another view controller, but the:
performSegueWithIdentifier(identifier: String, sender: AnyObject?)
function is not recognised, how to fix that ?
Edit:

-performSegueWithIdentifier: method is declared in UIViewController. So you can't just call it in UITableViewCell subclass.
You can add an action to that button when you are creating cell in -tableView:cellForRowAtIndexpath: method. Then you can call -performSegueWithIdentifier: method in that action method. Here is example assuming we are in UITableViewController subclass:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.button.addTarget(self, action: "someAction", forControlEvents: .TouchUpInside)
return cell
}
And here is action method:
func someAction() {
self.performSegueWithIdentifier("moveToView", sender: self)
}

You need a custom class for your cell. In that class, create an #IBAction as response to the button click. In that action, perform your segue.

If you are using Interface Builder:
Connect your firstViewController to the secondViewController - and create a Segue Identifier.
Then you are able to use
performSegueWithIdentifier(identifier: String, sender: AnyObject?)

Related

Is there an alternative for function Present in a UItableViewCell? [duplicate]

This question already has answers here:
UIButton action in table view cell
(11 answers)
Closed 3 years ago.
I want to navigate from UITableViewCell(Xib) to UIViewController but when I try to use present Value of type 'TableViewCell' has no member 'present
So if anyone is familiar with a function that can help me navigate please help me :) .
Thank you for your time
UITableViewCell can’t present viewcontroller. Please store viewController to variable in your tableview cell. And use it to present.
Or use didSelectRowAt delegate function and using self to present ( Or write your custom cell delegate if your event fire by button in cell)
Conform your ViewController to UITableViewDelegate protocol and then in your ViewController code use the delegate method: func tableView(UITableView, didSelectRowAt: IndexPath) and inside this method perform/present a segue or any other type of navigation you have.
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(UITableView, didSelectRowAt: IndexPath) {
// navigation logic here
}
}
Use closure inside your custom UITableViewCell to handle this scenario.
In your custom UITableViewCell create a handler and call it when the button is tapped inside the cell, i.e.
class CustomCell: UITableViewCell {
var handler: (()->())?
#IBAction func onTapButton(_ sender: UIButton) {
handler?()
}
}
Now, set the handler in cellForRowAt when creating the cell, i.e.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.handler = {
//present your controller here...
}
return cell
}

I want to prevent a navigation controller segue from happening when a row is tapped, but do want to segue when the accessory button is tapped

I'm getting an unwanted segue when I tap a tableview cell. I only want to do the segue when the accessory button is tapped. The current code works when I tap the accessory button on a cell. But if I tap the content view, a segue happens and my prepare(for:sender:) fails because sender isn't an IndexPath, it's an TableViewCell. BTW, the view containing the TableView is on a navigation controller stack.
I tried deselecting User Interaction Enabled setting for the content view of the table view cell, but that seems to inhibit the accessory button also.
This works as expected
func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
performSegue(withIdentifier: "ShowDetails", sender: indexPath)
}
When the cell is tapped, this is getting called before the prepare(for:sender:) is called.
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
log.debug("didHightlightRowAt")/
}
I don't know how to prevent the segue when the cell is tapped. When the cell calls the prepare(for:sender:), I get this error:
Could not cast value of type 'UITableViewCell' (0x11edbdaa0) to 'NSIndexPath' (0x10e209cf8).
2019-06-06 12:10:24.086845-0500 Earthquakers[1668:53901] Could not cast value of type 'UITableViewCell' (0x11edbdaa0) to 'NSIndexPath' (0x10e209cf8).
when this code executes:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is DetailViewController {
let indexPath = sender as! IndexPath
(because sender is a tableviewcell)

Perform Segue from Button in TableViewCell

I have a CustomCell class that has a button. I am using a prototype cell (not a .xib). I would like to have the button in a tableviewcell perform a segue and pass a value to a new class. How do I create a unique action for a button in a tableviewcell? Thanks!
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
selectedAreaCode = areaCodes[indexPath.row]
// Configure Cell
cell.areaCodeButton.setTitle(areaCode, forState: UIControlState.Normal)
cell.areaCodeButton.addTarget(self, action: "segue", forControlEvents: UIControlEvents.TouchUpInside)
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func segue() {
self.performSegueWithIdentifier("toDialer", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "toDialer") {
let nextViewController = (segue.destinationViewController as! PhoneDialer)
nextViewController.passedAreaCode = selectedAreaCode
}
}
There's a bunch of ways to get the tap action from your custom cell, but I'm assuming that you're trying to retrieve the action from a UIViewController because you're trying to segue.
Because you're dequeueing a cell, you briefly have full access to the cell in the scope of your cellForRowAtIndexPath function. As long as you have the button as a public property of the cell, you can set that button's target to your segue method.
Also, because what you're trying to pass is in the title of the button itself, you can just access the sender from the selector.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = yourCell()
cell.button.addTarget(self, action: #selector(tap(:)), forControlEvents: .TouchUpInside)
}
func segue(sender: UIButton) {
// Perform segue and other stuff
sender.title // This is the area code
}

Running a Segue within a UITableViewCell Swift 2

I have a button within a UITableViewCell and need to perform a following to another View.
How can I do this?
class CustomCell: UITableViewCell {
#IBAction func btnShowView(sender: AnyObject) {
performSegueWithIdentifier("seguePrincipalImagem")
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
Instead of having the code on the cell directly (although you can also make it with delegation), you can add the code directly to your controller and bind the method to the button, something like this:
Create a function that perform the segue on your UIViewController
func btnShowView(sender: AnyObject) {
self.performSegueWithIdentifier("segue_identifier",selder:nil)
}
In the process of creating the cell that has the button (in tableView:cellForRowAtIndexPath:):
//Inside tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier",indexPath) as! YourCustomTableViewCell
cell.yourBtn.addTarget(self, action: "btnShowView", forControlEvents: .TouchUpInside)
//More code to configure cell...
return cell
And that's it.

Push view controller when cell is tapped

I have tableViewController which pulls data from Parse. This calls inherits from UINavigationControllerDelegate.
I want to push a new view controller when the user taps on a cell. It seems like a simple task but I can't get it to work. I have first tried just simply making a push segue in my storyboard but nothing happens when I tap on the cell. I have tried to do it programmatically but the app crashes when I tap on the cell. I get a breakpoint error on the instantiation line:
import UIKit
import Foundation
import Parse
class PFViewController: PFQueryTableViewController, UITableViewDataSource, UINavigationControllerDelegate {
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let vc: Podcast = self.storyboard?.instantiateViewControllerWithIdentifier("Podcast") as Podcast
self.navigationController?.pushViewController(vc, animated: true)
}
}
Any ideas please?
To create the segue, ctrl-drag from the TableViewController to the destination viewController:
Then select the segue and give it an identifier in the property inspector:
Now you are able to perform this segue in code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
performSegueWithIdentifier("mySegue", sender: cell)
}