I have a set up that transfers info (the index for the cell selected) in a tableViewController so that the destination UIViewController can display some text info on a label by calling the appropriate index from an array. This all works correctly. However, there are 3 sections and I want the destination UIViewController to know which section was selected. (Ie. selecting the first cell in section 1 and the first cell in section 2 both return an index of 0, but I need it to be differentiable). I thought of passing the value of the selected section (and then setting up an if/else statement in the destination UIViewController) but I am not sure how to do that appropriately.
Here is the current code I have for the non-differentiating index pass:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let indexPath = self.tableView.indexPathForSelectedRow
let rowSelectedd = indexPath?.row
let destViewController: Controller = segue.destination as! Controller
destViewController.rowSelected = rowSelectedd!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "rowSelected", sender: rowSelectedd)
}
Basically, how do I pass the value of the section of the selected cell?
If the destination controller needs both the row and section of the selected row, then use an IndexPath property instead of an Int property and pass the whole indexPath instead of just indexPath.row.
But why does the destination controller need to know the index path? That makes no sense. Why not pass the actual data for that index path (from your data model) to the destination controller?
Related
First of all I would like to describe what actually I am trying to do.
I have two tableViewControllers - first one contains a list of bill's numbers and second one should displays the detail information about the bill depending on which cell of bill's number were selected.
In my first tableViewController I am using this to get bill's number from the cell and pass it to detailTableViewController:
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!) as! CustomBillTableViewCell
valueToPass = currentCell.billNumberLabel.text
print(valueToPass)
performSegue(withIdentifier: "billsDetailSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "billsDetailSegue"){
let detailController = segue.destination as! BillsDetailTableViewController
detailController.receivedValue = valueToPass
}
}
The problem is that didSelectRowAt function doesn't get triggered at all, after cell selection in the first tableView only prepare function triggers and It passes an empty value to the next view.
you override didDeselect instead of didSelectRowAt.
And you probably set a segue for tapping on cell.
Disconnect it and connect segue from your whole viewController.
Maybe you set your UITableView's selection styles to non-clickable.
Make UITableView -> Selection -> Single Selection and UITableViewCell -> Selection -> Default or something except the None
Make sure that you have set the delegate properly
EDIT 2: Added a half-solution at bottom. Still open to a full solution
EDIT 1: Added images.
I need help fixing navigation between a second and third tableview.
I have a Navigation Controller, and three table views. The first two show up fine such that clicking a dynamic tableview cell > in the first tableview moves to the second tableview. However the second tableview cell chevron > while set in the storyboard (Accessory: Disclosure Indicator) doesn't show up during runtime, and therefore clicking on it does not move to the third tableview. I need help fixing that.
In each case I Ctrl+linked the cells to the next tableview in storyboard as show, and have prepare for segue in the previous tableview controllers. However only one works and the other seems orphaned.
If you could suggest a checklist in making sure the Navigation Controller works across three tableviews that would be helpful. Not sure what code to show so I'll post both segues. But it might not be a segue issue so I don't know.
first tableview Weeks works going to second tableview Leagues. Loads json file depending on what is clicked.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toLeagues"
{
let leaguesController = segue.destination as! LeaguesViewController
// pass the selected row
let selectedRow = self.tableView.indexPath(for: sender as! UITableViewCell)!.row
if selectedRow == 0
{
leaguesController.weekFileName = "sports_week_1"
}
else
{
leaguesController.weekFileName = "sports_week_2"
}
}
But second tableview Leagues doesn't work going to third tableview Games
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toGames"
{
let gamesController = segue.destination as! GamesViewController
// pass the selected row
let selectedRow = self.tableView.indexPath(for: sender as! UITableViewCell)!.row
gamesController.gameName = selectedRow.description
}
}
EDIT 1: Added images:
Starts off fine in first tableview...
Stops here in second tableview, can't move to third tableview
EDIT 2: Half solution
I found a half solution. Menu item now opens new view, only that the chevron appears after the fact. didSelectRowAt adds the missing disclosure indicator directly and goes to the new view controller. Couldn't find a viewWillAppear with IndexPath so I opted for didSelectRowAt. Works when clicked at least. Just the disclosure indicator missing on initial load. How to load the accessoryType before the view runs?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = .disclosureIndicator
// force menu to move to GamesViewController
let myGamesView = self.storyboard!.instantiateViewController(withIdentifier: "gamesView")
self.navigationController?.pushViewController(myGamesView, animated: true)
}
Try setting accessoryType in cellForRowAt instead of didSelectRowAt.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourIdentifier") as! YourCustomCell
//Your other code
cell.accessoryType = .disclosureIndicator
return cell
}
In my first table view I have an array which populates the table view. The user then clicks a cell. Each cell has a different text label. I want to carry the label value from one table view to the next, but when it gets to the other table view the variable I try to set it to is nil. I am using segues and have tried to use prepareForSeguge function. I just can't get the variable to save once it's left the didSelectRowatIndexPath method.
EDIT: I used an observer to check that my variable was being set, but it isn't set until after all other functions have run. How Would I then be able to use my variable in my second tableview to populate the table?
Here is my code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow;
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!;
GenreSelector = currentCell.textLabel!.text
print(GenreSelector)
performSegueWithIdentifier("letsGo", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "letsGo") {
// initialize new view controller and cast it as your view controller
let viewController = segue.destinationViewController as! ResultTableViewController
// your new view controller should have property that will store passed value
viewController.GenreSelection = GenreSelector
}
}
I need to pass a variable containing the index of the selected row in one view to the next view.
firstview.swift
var selectedRow = 0;
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row + 1
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "viewAssignmentsSegue") {
let navController = segue.destinationViewController as! UINavigationController
let controller = navController.viewControllers[0] as! AssignmentsViewController
print(selectedRow)
controller.activeCourse = selectedRow
}
}
My issue is that, when a row is selected, the selectedRow variable isn't updated by the tableView method before the segue occurs, meaning that the value is essentially always one behind what it should be. How can I delay the prepareForSegue until the variable is updated or how else can I successfully pass the selected row to the next view without delay?
One possibility: Don't implement didSelectRowAtIndexPath:. Just move that functionality into your prepareForSegue implementation. That, after all, is what is called first in response to your tapping the cell. Even in prepareForSegue you can ask the table view what row is selected.
Another possibility: Implement willSelectRowAtIndexPath: instead of didSelectRowAtIndexPath:. It happens earlier.
in your prepareForSegue:
controller.activeCourse = self.tableView.indexPathForSelectedRow
don't wait for didSelect to be called - react earlier.
Use this on prepareForSegue:
let path = self.tableView.indexPathForSelectedRow()!
controller.activeCourse = path.row
or
let path = self.tableView.indexPathForCell(sender)
controller.activeCourse = path.row
I have a UITableView which I have set up to go to a different VC when a row is selected by the user (the table only consists of one array). I want to pass the row index of the selected item. I am using didSelectRowAtIndexPath to set a variable named selectedCellIndex to the row index. However, since I also have the tableView set up to go to the next VC prepareForSegue fires off (or around the same time) as didSelectRowAtIndexPath. As a result the first time I select an item from the list the value sent is nil, after that I always get the previous value of the row selected. Any Ideas on how to make sure that the variable is set before the app transitions to the next segue without putting a pause?
Here is my code:
var selectedCellIndex:Int!
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
var indexPath = tableView.indexPathForSelectedRow() as NSIndexPath?
selectedCellIndex = indexPath?.row as Int?
}
//SEGUE
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "signature" {
let vc = segue.destinationViewController as SignatureViewController
vc.index = "\(selectedCellIndex)"
}
}
Thanks
You can get the selected index path from the table view directly using the indexPathForSelectedRow method. There is no need to implement didSelectRowAtIndexPath just to store the selected index.
The prepareForSegue: method is the only method where you should set/access variables that are necessary for a transition.