Sending indexPath.row from didselectRowAtIndexPath to prepareForSegue via sender - ios

I have seen many solutions however i cant get this right. I want to call prepareForSegue from the didSelectRowAtIndexPath function when a cell is tapped. Then i want to retrieve the row index that was tapped on, from inside the prepareForSegue function so i can use it to pass information to another view. I think i am calling the function correctly but there is something going wrong in my prepareForSegue function. I know its an easy solution i am just very stuck. Heres my current code
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("notificationsToAnswers", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//the below line is incorrect and should be something else
let selectedIndex = tableView.indexPathForSelectedRow?.row
//pass data on using the index
}

You should pass like this:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("notificationsToAnswers", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "notificationsToAnswers" {
//the below line is incorrect and should be something else
let selectedIndexPath = sender as! NSIndexPath
let index = selectedIndexPath.row
//pass data on using the index
}
}

Related

Pass var from selected TableView Cell Swift Xcode

I'm a beginner in Swift (Xcode) and I need help. I have a tableview and I want to send information from the indexPath.row to a segue.
My script work, but the problem is the data send to my segue is the previous selected row and not the current cell select. Because the function prepare segue is called before the func tableView. That's make 2 days I search and every tutorial give me the same problem.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
jobname = filldata[indexPath.row]
print(jobname)
performSegue(withIdentifier: "jobsegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "jobsegue" {
let destVC = segue.destination as! JobNameViewController
destVC.jobname = jobname
}
}
Thank you sooo much for your help!
Try this, this will work fine:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "jobsegue", sender: indexPath.row)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "jobsegue" {
let destVC = segue.destination as! JobNameViewController
destVC.jobname = filldata[sender]
}
}

I need to override a segue function after clicking a

So I have this tableView and I want when clicking a cell it gives me the name of that cell, and I pass it to next view, but the problem is that I need to override segue function inside of the "didselectrowAt" function and that is impossible I guess, any suggestion on how to do this?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
clickedYear = years[indexPath.row]
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let ResumosVC: Resumos2ViewController = segue.destination as! Resumos2ViewController
ResumosVC.Title = clickedYear
}
Two solutions:
Reconnect the segue to the cell (rather than to the controller) and implement
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let cell = sender as? UITableViewCell,
let indexPath = tableView.indexPath(for: cell) else { return }
let resumosVC = segue.destination as! Resumos2ViewController
resumosVC.Title = years[indexPath.row]
}
Call performSegue in didSelect (replace the identifier string with the real value)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "MySegueIdentifier", sender: indexPath)
}
and change prepare(for to
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let indexPath = sender as? IndexPath else { return }
let resumosVC = segue.destination as! Resumos2ViewController
resumosVC.Title = years[indexPath.row]
}
clickedYear is not needed in both cases.
Note: Please conform to the naming convention to name variables with starting lowercase letter.

Searched item returns wrong detail view on click

I am parsing some info from JSON using Firebase. I implemented search controller into the tableview, it returns correct items while searching but the problem is that on click (didSelectRowAtIndexPath) it returns wrong info. What could cause this, can you tell me guys?
This is the arrays in which I am searching:
var brands = [String]()
And this is the filtered array:
var filteredBrands = [String]()
And this is what I am doing inside the didSelectRowAtIndexPath:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedBrand = brands[indexPath.row]
performSegueWithIdentifier("toProducts", sender: self)
}
And like this I pass the selected value:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "toProducts") {
let snusProductsView = segue.destinationViewController as! SnusProductsTableViewController
snusProductsView.brandName = selectedBrand
print(self.selectedBrand)
}
}
But for some reason it passes the wrong value. It passes the first item inside tableView
Inside didSelectRowAtIndexPath you have to check is it filtered version or not if so you need to use filteredBrands instead of brands.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if isSearching {
selectedBrand = filteredBrands[indexPath.row]
} else {
selectedBrand = brands[indexPath.row]
}
I must be dumb... After posting I figured out what was the problem. My selectedBrand was wrong if the resultSearchController was active. So I fixed it like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "toProducts") {
let snusProductsView = segue.destinationViewController as! SnusProductsTableViewController
snusProductsView.brandName = selectedBrand
print(self.selectedBrand)
}
}

Swift 2 - prepareForSegue nil Value

I am trying to send a link over another view when a select a row in UITableView.
When I select the row I can see the link is printed however, the value does not get to the function prepareForSegue.
It seems like the prepareForSegue function is called before the selection row in UITableView.
var videouserPath = ""
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
videouserPath = self.arrayUserVideo[indexPath.row][4]
print("tableview: ----\(videouserPath)")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("segue: ----\(videouserPath)")
if segue.identifier == "toUserVideo"
{
if let destinationVC = segue.destinationViewController as? GetVideo_ViewController{
destinationVC.videoToDisplay = videouserPath
}
}
}
I got in debug:
segue: ----
tableview: ----https://example.com/resources/1361929513_02-02-2016_125830.mov
Why is the segue function called before selection?
When linking UIStoryboardSegue to UITableViewCell from the storyboard, the messaging is in the order prepareForSegue, didSelectRowAtIndexPath.
Automatic Method
Bypass didSelectRowAtIndexPath altogether.
For general purpose and single selection cells, you do not need to implement didSelectRowAtIndexPath. Let the segue associated with UITAbleViewCell do the work, and handle selection like so:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detailSegueIdentifier" {
if let indexPath = tableView.indexPathForSelectedRow {
print(indexPath)
}
}
}
Manual Method
If you absolutely need to do extra work before the segue, do not associate it to the UITableViewCell but to the UITableViewController. You will then need to trigger it programmatically. Inspiration here.
In IB, assign the segue to table view controller, give it an identifier (say detailSegueIdentifier), and invoke it like so.
override func tableView(tableView: UITableView,
didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("didSelectRowAtIndexPath")
self.performSegueWithIdentifier("detailSegueIdentifier", sender: nil)
}
Passing parameters to the segue:
Invoking performSegueWithIdentifier will also give you a chance to explicitly pass parameters, not second-guess indexPathForSelectedRow, and not rely on a global(*).
override func tableView(tableView: UITableView,
didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("didSelectRowAtIndexPath")
self.performSegueWithIdentifier("detailSegueIdentifier", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detailSegueIdentifier" {
if let indexPath = sender as? NSIndexPath {
let name = db[indexPath.row].key
if let controller = segue.destinationViewController as? DetailViewController {
controller.name = name
}
}
}
}
(*) Don't ever rely on globals if you can help it.

Swift tableView and prepareForSegue functions

I am trying to get the tableView function to change the row before it goes into the prepareForSegue function. Below are the two functions:
This function is called when a cell is clicked and it changes the row variable to the current row that is clicked
override func tableView(tableView: UITableView,
didSelectRowAtIndexPath indexPath: NSIndexPath) {
row = indexPath.row
NSLog("You selected cell number: \(indexPath.row)!")
}
This function is for the segue from the cell that is clicked to the next window
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var destViewController = segue.destinationViewController as! SecondView
destViewController.nameString = namesArray[getRow()]
}
I'm not sure what the getRow() method is, but it looks like you should just directly use your global row variable.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var destViewController = segue.destinationViewController as! SecondView
destViewController.nameString = namesArray[row] // use your global variable row here
}

Resources