The code in question:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
var card: String
if (tableView == self.searchDisplayController?.searchResultsTableView){
card = self.filtered[indexPath.row]
}
else{
card = self.array[indexPath.row]
}
let destinationVC = SearchViewController()
destinationVC.searchString = card
destinationVC.performSegueWithIdentifier("ResultSegue", sender: self)
}
I'm trying to pass a string to another view when a cell in my table is selected. In the storyboard I named the segue identifier 'ResultSegue'.
What happens when I run my app is when I click a cell it loads the next view, without the variable I'm sending being updated, then if I go back and click on a new cell the app will crash and give me the titled warning.
I've tried running clean, and resetting the simulator as other threads have suggested, but nothing changes.
You should pass a the string in prepareForSegue function rather than didSelectRowAtIndexPath function.
Instead of using didSelectRowAtIndexPath as below:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ResultSegue" {
if let indexPath = self.tableView.indexPathForSelectedRow() {
var card: String
if (tableView == self.searchDisplayController?.searchResultsTableView) {
card = self.filtered[indexPath.row]
} else {
card = self.array[indexPath.row]
}
(segue.destinationViewController as SearchViewController).searchString = card
}
}
}
Related
I have seen two similar questions here but none of their answers really helped me.
I have a tableView of comments and I want to perform a segue to a detail of the comment (kind of like twitter does, if you click on a tweet you have a detail view of it). However the information given to the detail view is the penultimate row selected and not the last selected. And if you only select one, the segue wont be even performed.
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("detail_segue", sender: indexPath)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detail_segue"){
let row = (sender as! NSIndexPath).row;
let commentForSegue = self.AOS[row]
let destinationVC = segue.destinationViewController as! CommentDetailVC
destinationVC.detail_title = commentForSegue.titulo_comment
destinationVC.detail_body = commentForSegue.cuerpo_comment
destinationVC.detail_date = commentForSegue.fecha_comment
destinationVC.detail_num_agree = String(commentForSegue.num_agrees)
destinationVC.detail_num_disagree = String(commentForSegue.num_disagrees)
destinationVC.detail_agreed = commentForSegue.agreed
}
}
I've tried with and without the dispatch_async both on the prepareForSegue and didSelectRowAtIndexPath but it doesnt work. I've also tried doing all the work from the didSelectRowAtIndexPath but no success either.
Thanks!!
First of all, you need to call the segue in the method didSelectRowAtIndexPath and you're calling it from the method didDeselectRowAtIndexPath exist a little difference between both, but are some tips to get the last cell tapped too, see the following code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// the identifier of the segue is the same you set in the Attributes Inspector
self.performSegueWithIdentifier("detail_segue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detail_segue"){
// this is the way of get the indexPath for the selected cell
let indexPath = self.tableView.indexPathForSelectedRow()
let row = indexPath.row
let commentForSegue = self.AOS[row]
let destinationVC = segue.destinationViewController as! CommentDetailVC
destinationVC.detail_title = commentForSegue.titulo_comment
destinationVC.detail_body = commentForSegue.cuerpo_comment
destinationVC.detail_date = commentForSegue.fecha_comment
destinationVC.detail_num_agree = String(commentForSegue.num_agrees)
destinationVC.detail_num_disagree = String(commentForSegue.num_disagrees)
destinationVC.detail_agreed = commentForSegue.agreed
}
}
I hope this help you.
I have a tableView displaying all the users on ViewController1(VC1) when the currentUser chooses a cell it segues to ViewController2(VC2) and needs to display all the user information from the cell that was clicked onto labels and a PFImageView. I have all the user info for the last cell displaying. So even though I clicked a different cell the next VC is only displaying the user at the end of the list. So lets say my user cell list display starts with Aisling, roger, dave and john. I click on cell 'Aisling' and segue to VC2, it displays all of Johns profile info.
VC1:
under the class:
var appUsers = [PFUser]()
var userToShow = PFUser()
then:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let singleCell: CustomCell = tableView.dequeueReusableCellWithIdentifier("mySingleCellid") as! CustomCell
let userObject = appUsers[indexPath.row] as PFObject
singleCell.userName.text = userObject["name"] as? String
singleCell.userAge.text = userObject["age"] as? String
singleCell.usersProfileImage.file = userObject["image"] as? PFFile
singleCell.usersProfileImage.loadInBackground()
// when userToShow is here it shows the user detail of the last cell everytime
userToShow = appUsers[indexPath.row]
return singleCell
} // cell for row
// when userToShow is here it crashes the app when the cell is clicked giving the error:unexpectedly found nil while unwrapping an Optional value
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
userToShow = appUsers[indexPath.row]
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "userProfileDetailsSegue" {
if let destinationVC = segue.destinationViewController as? UserProfileDetailsViewController {
destinationVC.userToShowDetail = userToShow
}
}
}
}
On VC2:
below the class:
var userToShowDetail = PFUser()
Then:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
userName.text = userToShowDetail["name"] as? String
userBio.text = userToShowDetail["bio"] as? String
userAge.text = userToShowDetail["age"] as? String
userProfile.file = userToShowDetail["image"] as? PFFile
userProfile.loadInBackground()
}
It only displays in VC2 the user details belonging to the user in the last cell on VC1. Instead of the user details belonging to the user in the cell that was chosen.
Stuck on this for a few weeks now and my deadline is pushing on can't solve it any help would really be appreciated!!! All links and help I could find online is for C# and obj c.
VC1
//PUT THIS IN THE FIRST VC CLASS
var appUserResult: PFUser?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//TAKE OUT LET - YOU'VE ALREADY DEFINED AS CLASS VAR
appUserResult = appUsers[indexPath.row]
print(appUserResult)
self.performSegueWithIdentifier("openVC2", sender: self)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "openVC2" {
let indexPath = self.resultsPageTableView.indexPathForSelectedRow!
//INDEXPATH ISN'T AVAILABLE IN PREPAREFORSEGUE
//let userToShow = appUsers[indexPath.row]
let newVc = segue.destinationViewController as! UserProfileDetailsViewController
//USE THE CLASS VARIABLE TO PASS
newVc.userToShowDetail = appUserResult
VC2
var userToShowDetail: PFUser?
In storyboard, delete the old segue. Create a new one from VC1 to VC2 (not from the table cells). Give it the identifier "openVC2".
I have a view crontroller called "subcateory2", this viewcontroller has a uicollectionview wit custom cell. I need two segues from my app. One of the called "to_videostable" from the viewcontroller to other view controller and the other calles "reload_collection" from the cell to the same viewcontroller(because the subcategory can have n-level of subcategories). The problem is with my prepareForSegue(i check in this function the identifier , that is defined in the " func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)",and execute different actions). When i select a cell this should happen:
first: go to my "func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)", check the condition and define my identifier for segue.
second: go to the prepareforsegue, check the condition and execute the actions.
but actually this happen:
first: in my ios simulator i select a cell.
second: my code go the prepareforsegue and go always for the segue called "reload_collection"(before going to my func collectionView(...)), and create a white views. In this moment is like a two threads are created, one of them go to the white windows and the other to the next stop.
third: this "second theard" go to the func collectionview(...) and check the condition, define the identifier, call to the performSegueWithIdentifier and go to the prepareforsegue function. In the prepareforsegue check the identifier and execute the differentes actions.
This is my code:
import UIKit
class Subcategory2: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
let viewUtils = ViewControllerUtils()
var result_category: Array<JSON> = []
#IBOutlet weak var collectionview: UICollectionView!
var tit: String!
var url: String!
var end_url:String = "?page_size=100"
var id_category: Int!
var index: NSIndexPath!
var url_children : String = ""
let imagePath = "http://d1rkb03u2ginv9.cloudfront.net/wp-content/uploads/"
override func viewDidLoad() {
self.viewUtils.showActivityIndicator(self.view)
super.viewDidLoad()
self.viewUtils.showActivityIndicator(self.view)
if self.result_category.isEmpty{
var category = category_function()
self.url = self.url + self.end_url
self.result_category = category.load_subcategory(self.url)}
self.viewUtils.hideActivityIndicator(self.view)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
var cell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
println("entroooooooo")
if (self.result_category[indexPath.row]["children"].string != nil){
self.url_children = self.result_category[indexPath.row]["children"].string!
//while(self.url_children.isEmpty){}
println("voy a reloadcollection")
performSegueWithIdentifier("reload_collection", sender: cell)
//performSegueWithIdentifier("reload_collection3", sender: self)
}else{
println("voy a to_videostables")
performSegueWithIdentifier("to_videostable", sender: cell)
}
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//println(result_category.count)
return result_category.count }
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) ->UICollectionViewCell {
let cell: CollectionViewCellController2 = collectionView.dequeueReusableCellWithReuseIdentifier("cell2", forIndexPath: indexPath) as! CollectionViewCellController2
println(self.result_category[indexPath.row]["slug"].stringValue)
cell.label.text = self.result_category[indexPath.row]["slug"].stringValue
if (self.result_category[indexPath.row]["images"]["file"].string != nil){
//println("+++++++++++++++++")
var image = self.result_category[indexPath.row]["images"]["file"].stringValue
cell.image.sd_setImageWithURL(NSURL(string:self.imagePath + (image as! String)))
}else{
var image = "http://www.camping-oaza.com/images/joomlart/demo/default.jpg"
cell.image.sd_setImageWithURL(NSURL(string: image))
//cell.image.image = UIImage(named: image)
}
cell.NumberVideosLabel.text = self.result_category[indexPath.row]["videos_count"].stringValue
cell.NumberSubcategoryLabel.text = self.result_category[indexPath.row]["children_count"].stringValue
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "to_videostable"{
println("-------------")
println("voy a to_videostables")
let cell = sender as! UICollectionViewCell
let index = self.collectionview!.indexPathForCell(cell) // this return -> NSIndexPath?
//if (self.result_category[index!.row]["children"].string != nil){
// self.loaddata(self.result_category[index!.row]["children"].string!)
//}else{
let vc : VideosViewController = segue.destinationViewController as! VideosViewController
println(self.result_category[index!.row]["id"].intValue)
vc.id_category = self.result_category[index!.row]["id"].intValue
}
if segue.identifier == "to_livevideos"{
println("-------------")
println("to_livevideos")
println("-------------------")
let vc : SWRevealViewController = segue.destinationViewController as! SWRevealViewController
}
if segue.identifier == "reload_collection"{
println("-------------")
println("reload_collection")
println("-------------------")
var category = category_function()
let vc : Subcategory2 = segue.destinationViewController as! Subcategory2
vc.url = self.url_children
println(category.load_subcategory(self.url_children + self.end_url))
}
}
}
With this problem, always is created a white windows and after is created a windows with the real information.
the order of the println is :
- "reload_collection"
- "entroooooooo"
- "voy a reloadcollection" or "voy a to_videostables"
In this pictures show my main.stoyboard and the windwos that i can see in my app.
Updated Answer
You have a situation where you want to decide which segue to take when a cell is selected. You have wired one of your segues directly from the cell, which means the storyboard will create that segue for you. You also are calling performSegueWithIdentifier which creates another segue. You need to implement shouldPerformSegueWithIdentifier to cancel the "reload_collection" segue when you want segue to "to_videostables".
In the Original Answer below, I suggested you wire both segues from the viewController, but that won't work because one of your segues is back to the same viewController.
So, another way to do this is to:
Modify didSelectItemAtIndexPath to remove the code that handles the "reload_collection" segue. The Storyboard will be making that segue:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
var cell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
println("entroooooooo")
if result_category[indexPath.row]["children"].string == nil {
println("voy a to_videostables")
performSegueWithIdentifier("to_videostable", sender: cell)
}
}
Wire the segue "reload_collection" from the cell to the viewController. This will allow the Storyboard to perform this segue for you.
Implement shouldPerformSegueWithIdentifier to tell the Storyboard when it should make this segue:
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
if segue.identifier == "reload_collection" {
let indexPath = collectionView.indexPathForCell(sender as! UICollectionViewCell)
return result_category[indexPath.row]["children"].string != nil
}
return true
}
In prepareForSegue you will need to set up url_children since it is no longer being done by didSelectItemAtIndexPath:
if segue.identifier == "reload_collection"{
println("-------------")
println("reload_collection")
println("-------------------")
var category = category_function()
let vc : Subcategory2 = segue.destinationViewController as! Subcategory2
let indexPath = collectionView.indexPathForCell(sender as! UICollectionViewCell)
url_children = result_category[indexPath.row]["children"].string!
vc.url = url_children
println(category.load_subcategory(self.url_children + self.end_url))
}
Original Answer
Your segue is getting auto-called because you have wired it from the cell. If you want to trigger it with performSegueWithIdentifier it needs to be wired from the viewController like the other segue. Just remove the segue from the cell and rewire it from the viewController and give it the same identifier it had when you wired it from the cell and it should work.
Hello StackOverflow,
I'm just picking up swift and trying to implement data being passed between UITableView Cell to a UIViewController which will show a detailed view of the info shown on the tableview, and whenever I test the application on my emulator first time I press a table cell it passes an empty string and then when I try pressing another cell the viewController shows the string that was supposed to be seen earlier.I pasted the code I have for my tableview didSelectRowAtIndexPath below.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
var7 = lat[indexPath.item]
var6 = long[indexPath.item]
var5 = items[indexPath.item]
var1 = detail[indexPath.item]
var2 = date[indexPath.item]
var3 = wop[indexPath.item]
var4 = ViewController()
nextView.locationPassed = var1
//self.performSegueWithIdentifier("DetailPush", sender: self)
println("value stored in var1: \(var1)")
//println("The selected indexPath is \(indexPath.item + 1)")
println("The stored id is: \(storeSend)")
}
Here is my implementation for my push segue method
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "DetailPush"
{
if let crimesView = segue.destinationViewController as? ViewController {
crimesView.locationPassed = var1
//println("The passing address is: \(var1)")
}
}
}
Any idea on why I'm getting data delayed during the segue?
Thank you
Solution Found: I edited my prepareForSegue method with the following and it fixed my issue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//Adding the indexPath variable for the selected table Row within the segue
var indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow()!
if segue.identifier == "DetailPush"
{
if let crimesView = segue.destinationViewController as? ViewController {
//Then just pass the data corresponding to the array I created identified by the index of the selected row
crimesView.locationPassed = self.arrayName[indexPath.row]
println("The passing address is: \(self.addressSend)")
}
}
}
I found the solution by watching some online videos and all I did to fix my issue was redefine my prepareForSegue function with:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//Adding the indexPath variable for the selected table Row within the segue
var indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow()!
if segue.identifier == "DetailPush"
{
if let crimesView = segue.destinationViewController as? ViewController {
//Then just pass the data corresponding to the array I created identified by the index of the selected row
crimesView.locationPassed = self.arrayName[indexPath.row]
println("The passing address is: \(self.addressSend)")
}
}
}
And it seems to work like a regular segue for me.......Thank you for all the suggestions given me
you said you are doing the prepareForSegue from async request
so try this:
if segue.identifier == "DetailPush"
{
dispatch_async(dispatch_get_main_queue()) {
if let crimesView = segue.destinationViewController as? ViewController {
crimesView.locationPassed = var1
//println("The passing address is: \(var1)")
}
}
}
try to remove the line
tableView.deselectRowAtIndexPath(indexPath, animated: false)
see if it still happens.
maybe move it to the end
I'm encountering problems with my UITableViewCells. I connected my UITableView to a API to populate my cells.
Then I've created a function which grabs the indexPath.row to identify which JSON-object inside the array that should be sent to the RestaurantViewController.
Link to my Xcode Project for easier debugging and problem-solving
Here's how my small snippet looks for setting the "row-clicks" to a global variable.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
i = indexPath.row
}
And here's my prepareForSegue() function that should hook up my push-segue to the RestaurantViewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toRestaurant"{
let navigationController = segue.destinationViewController as UINavigationController
let vc = navigationController.topViewController as RestaurantViewController
vc.data = currentResponse[i] as NSArray
}
}
And here's how I've set up my segue from the UITableViewCell
Here's my result, I've tried to click every single one of these cells but I won't be pushed to another viewController...I also don't get an error. What is wrong here?
Tried solutions that won't work
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toRestaurant"{
let vc = segue.destinationViewController as RestaurantViewController
//let vc = navigationController.topViewController as RestaurantViewController
vc.data = currentResponse[i] as NSArray
}
}
The problem is that you're not handling your data correctly.
If you look into your currentResponse Array, you'll see that it holds NSDictionaries but in your prepareForSegue you try to cast a NSDictionary to a NSArray, which will make the app crash.
Change the data variable in RestaurantViewController to a NSDictionary and change your prepareForSegue to pass a a NSDictionary
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if let cell = sender as? UITableViewCell {
let i = redditListTableView.indexPathForCell(cell)!.row
if segue.identifier == "toRestaurant" {
let vc = segue.destinationViewController as RestaurantViewController
vc.data = currentResponse[i] as NSDictionary
}
}
}
For Swift 5
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if let cell = sender as? UITableViewCell {
let i = self.tableView.indexPath(for: cell)!.row
if segue.identifier == "toRestaurant" {
let vc = segue.destination as! RestaurantViewController
vc.data = currentResponse[i] as NSDictionary
}
}
}
The following steps should fix your problem. If not, please let me know.
Remove your tableView(tableView, didSelectRowAtIndexPath:) implementation.
Make data on RestaurantViewController have type NSDictionary!
Determine the selected row in prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if let cell = sender as? UITableViewCell {
let i = tableView.indexPathForCell(cell)!.row
if segue.identifier == "toRestaurant" {
let vc = segue.destinationViewController as RestaurantViewController
vc.data = currentResponse[i] as NSDictionary
}
}
}
Dropbox link to stack3 directory
I am having difficulty understanding why your software is much different than a standard 2 level tableview structure. So I coded a short example which you can access from this link. I have also included the sources code below.
The program mimics what you have (as best as I understood it). Table Controller 1 segues to Table Controller 2 from the tableview cell. I had no issues with segue-ing. Notice that I do not have nor need to augment the Storybook to initiate the segue.
I have embedded both the controllers in Navigation Controllers. My experience is that it saves a lot of effort to set up the navigation.
Alternately, I could have control-dragged from the first TableViewController symbol on top of the screen to the second controller and set up the segue.
I used a global variable (selectedRow) although it is not a recommend practice. But you just as easily use the prepareForSegue to set a variable in the RestaurantTableViewController (I show an example)
Finally, I recommend checking the Connections Inspector (for the table view cell in the first controller) to confirm that there is a segue to the second controller. If you control-dragged properly there should be confirmation prompt as well as an entry in the Connections Inspector.
Unfortunately I just cant get the code properly formatter
import UIKit
var selectedRow = -1
class TableViewController: UITableViewController {
var firstArray = ["Item1","Item2","Item3","Item4"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return firstArray.count
}
let nameOfCell = "RestaurantCell"
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell
cell.textLabel!.text = firstArray[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as RestaurantTableViewController
// can write to variables in RestaurantTableViewController if required
vc.someVariable = selectedRow
}
}
import UIKit
class RestaurantTableViewController: UITableViewController {
var secondArray = ["Item 2.1", "Item 2.2", "Item 2.3", "Item 2.4"]
var someVariable = -1
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return secondArray.count
}
let nameOfCell = "RestaurantCell"
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell
cell.textLabel!.text = secondArray[indexPath.row]
if indexPath.row == selectedRow {
cell.textLabel!.text = cell.textLabel!.text! + " SELECTED"
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
}
I noticed that in your screenshot of your storyboard, the segue is connecting the first prototype cell to the RestaurantViewController. This prototype cell looks like it's the "Basic" style of cell with a disclosure indicator accessory on the right. But look at the screenshot of your app running. The table is being populated with cells that appear to be the "Subtitle" style of cell without a disclosure indicator accessory on the right.
The reason that your segue is never firing no matter what you do is that the segue is only configured to work for a specific prototype cell, but that prototype cell is never being used when you populate the table. Whatever you're doing in tableView:cellForRowAtIndexPath:, you're not using the prototype cell that you want.
#Starscream has the right idea dequeueing the right cell with the right identifier and matching it with the identifier of the prototype cell in Interface Builder. The crash that you're getting even after doing that might be because of the previous problem mentioned in the comments above. Your segue in the storyboard is clearly pointing to a UITableViewController. Your code in prepareForSegue:sender: should be let vc = segue.destinationViewController as RestaurantViewController, as long as RestaurantViewController is a subclass of UITableViewController. You'll crash if you try to cast it as a UINavigationController. Also make sure that the class for the destination UITableViewController in the storyboard is listed as RestaurantController in the Identity Inspector pane. You'll crash if your program compiles thinking that the storyboard just contains a generic UITableViewController there.
Getting back to the original problem more, I don't know how you've implemented tableView:cellForRowAtIndexPath:, which might be crucial. Maybe it's not so simple. Maybe you plan on handling many prototype cells or generate custom cells at runtime. In this case, one way to make this simple for you is to programmatically perform the segue when the user taps on a cell. Instead of using a specific prototype cell, make the segue a connection originating from the "Restauranger nära mig" UITableViewController going to the RestaurantViewController. (Connect in Interface Builder by control-click dragging from the Table View Controller icon at the top of the first one over to the body of the second). You must give this segue an identifier in the Attributes Inspector pane to make this useful. Let's say it's "toRestaurant". Then at the end of your tableView:didSelectRowAtIndexPath: method, put this line of code: self.performSegueWithIdentifier("toRestaurant", sender: self). Now no matter what cell is selected in the table, this segue will always fire for you.
Try creating cells like this in your cellForRow method:
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyTestCell", forIndexPath: indexPath)
Im going out on a whim here since I am just getting into swift right now but the way I do it in my prepareForSegue() is something like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toRestaurant"{
let navigationController = segue.destinationViewController as UINavigationController
let vc = navigationController.topViewController as RestaurantViewController
//notice I changed [i] to [index!.row]
vc.data = currentResponse[index!.row] as NSArray
}
}
What it looks like to me is that you are calling the i variable which is kind of like a private variable inside a method of your class. You can do something like #Syed Tariq did with the selectRow variable and set it above your class SomeController: UIViewController /*, maybe some more here? */ { and then sign the variable inside your
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
method like above but both ways should work rather well.
I had the same problem and I found the solution to be:
performSegueWithIdentifier("toViewDetails", sender: self)
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cellnumber = procMgr.processos[indexPath.row].numero
println("You selected cell #\(indexPath.row)")
println(cellnumber)
performSegueWithIdentifier("toViewDetails", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toViewDetails" {
let DestViewController : ViewDetails = segue.destinationViewController as! ViewDetails
}
}
You may need to get the selected cell index of the UItableview. Below code used the selected cell index (UItableview.indexPathForSelectedRow) to get a correct element of the array.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "seguaVisitCardDetial" {
let viewController = segue.destinationViewController as! VCVisitCardDetial
viewController.dataThisCard = self.listOfVisitCards[(tblCardList.indexPathForSelectedRow?.row)!]
}
}
I had this problem, too; the segue from UITableViewCell did not call.
After some searching, I found it is because I had chosen "No Selection" for "Selection" field.