Segue lag, tableview in Swift - ios

I am working at my first application in Swift 3. I am using tableView (by "extension MainController: UITableViewDataSource"). And from this tableView, by storyboard I have two segues. One for editing (by clicking on accessory icon) and the second one for more detail screen (by clicking on a table row). I am not calling this segues by code, but by storyboard.
And my problem is that there is sometimes huge lag. Like after clicking on a row, the next screen is showing after 30 seconds. But now always. Sometimes its working immediately. Interesting thing is that when I touch row 1, and nothing happens, next I am clicking row 2 and then row 1 is appearing.
I am also using delegates, this is the code for preparing segues:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 1
if segue.identifier == "AddSensor" {
// 2
let navigationController = segue.destination
as! UINavigationController
// 3
let controller = navigationController.topViewController
as! AddController
// 4
controller.delegate = self
}
else if segue.identifier == "EditSensor" {
let navigationController = segue.destination
as! UINavigationController
let controller = navigationController.topViewController
as! AddController
controller.delegate = self
if let indexPath = tableView.indexPath(
for: sender as! UITableViewCell) {
controller.sensorToEdit = sensors[indexPath.row]
}
}
else if segue.identifier == "DetailSeq" {
let navigationController = segue.destination
as! UINavigationController
let controller = navigationController.topViewController
as! DetailController
controller.delegate = self
if let indexPath = tableView.indexPath(
for: sender as! UITableViewCell) {
controller.sensorRecieved = sensors[indexPath.row]
}
}
}
I was reading that it was common bug in iOS8 and could be resolved by adding
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
DispatchQueue.main.async {
self.performSegue(withIdentifier: "DetailSeq",sender: self)
}
}
But it didn't worked for me. I don't know what should I do next to resolve this problem. Can anyone guide me?

According to this SO question, you may be able to fix your bug if you present your view controller in code rather than with the segue in the storyboard. Something like this, where your destination is the VC that you want to go to.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath:
NSIndexPath) {
DispatchQueue.main.async {
self.presentViewController(destination, animated: true) { () -> Void
in
}
}
}

You have to use like this :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
DispatchQueue.main.async {
self.performSegue(withIdentifier: "DetailSeq",sender: self)
}
}

Related

UITableViewCell Segue SOMETIMES connects to wrong controller

I am having a very weird issue with my tableView, sometimes you click a cell and segues as it should, but other times it will segue to a random detailViewController.
I have 3 segues connecting from a UIViewController that contains tableview:
The segues "present modally" a detailViewController and pass a custom object "place" to the detailViewController
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("PLACE SELECTED: SECTION \(indexPath.section) ROW \(indexPath.row) :: \(my_sections[indexPath.section])")
self.selectedPlace = my_sections[indexPath.section].rows[indexPath.row]
let buttons_count = self.selectedPlace!.buttons.count
switch buttons_count {
case 0:
self.performSegue(withIdentifier: SegueIdentifier.NoButton.rawValue, sender: self.tableview.cellForRow(at: indexPath))
case 1:
self.performSegue(withIdentifier: SegueIdentifier.OneButton.rawValue, sender: self.tableview.cellForRow(at: indexPath))
case 2:
self.performSegue(withIdentifier: SegueIdentifier.TwoButton.rawValue, sender: self.tableview.cellForRow(at: indexPath))
default:
break
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (sender as? PlaceTableViewCell) != nil {
if let indexPath = self.tableview.indexPathForSelectedRow {
let place = self.my_sections[indexPath.section].rows[indexPath.row]
navigationController?.view.backgroundColor = UIColor.clear
switch(segue.identifier!) {
case SegueIdentifier.NoButton.rawValue:
assert(segue.destination.isKind(of: PlaceDetailsViewController.self))
let vc = segue.destination as! PlaceDetailsViewController
vc.place = place
case SegueIdentifier.OneButton.rawValue:
assert(segue.destination.isKind(of: OneButtonViewController.self))
let vc = segue.destination as! OneButtonViewController
vc.place = place
case SegueIdentifier.TwoButton.rawValue:
assert(segue.destination.isKind(of: TwoButtonViewController.self))
let vc = segue.destination as! TwoButtonViewController
vc.place = place
default: break
}
}
}
}
The place object has place.buttons: [Button]
The three detailViewControllers are almost identical except they have different number of buttons.
The tableView decides which segue to use based on the size of place.buttons
Sometimes the tableView works like normal and other times it passes random cells. Unsure why.
You can simplify your prepare(for: method to solve this as follows:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
navigationController?.view.backgroundColor = UIColor.clear
switch(segue.identifier!) {
case SegueIdentifier.NoButton.rawValue:
assert(segue.destination.isKind(of: PlaceDetailsViewController.self))
let vc = segue.destination as! PlaceDetailsViewController
vc.place = self.selectedPlace
case SegueIdentifier.OneButton.rawValue:
assert(segue.destination.isKind(of: OneButtonViewController.self))
let vc = segue.destination as! OneButtonViewController
vc.place = self.selectedPlace
case SegueIdentifier.TwoButton.rawValue:
assert(segue.destination.isKind(of: TwoButtonViewController.self))
let vc = segue.destination as! TwoButtonViewController
vc.place = self.selectedPlace
default: break
}
}
Seems like my_sections is array. Try sort it before access to it's items. I have simmular problem, when programm gets data from persistent store and items in the data array were unordered.
I figured out the problem and I am sorry to the people who took the time here, I did not give enough information for anyone to solve this problem.
my tableview gets information from
var my_sections: [Section] = [] {
didSet {
return self.my_sections.sort(by: { $0.index < $1.index})
}
}
My "Section" model looks like this:
struct Section: Ordered {
var section: PTPlace.Section
var rows: [PTPlace]
var sorted_rows: [PTPlace] {
return self.rows.sorted(by: { $0.open_status.rawValue > $1.open_status.rawValue })
}
}
I noticed something was up when rows were getting mixed up WITHIN sections but not between sections.
So I added the following line to didSelectRowAtIndexPath method:
print("PLACE SELECTED: SECTION \(indexPath.section) ROW
\(indexPath.row) :: \(my_sections[indexPath.section].rows[indexPath.row].name)")
And I saw that the tableView was arranged very differently than how the rows were sorted, as if there were two different arrays. And sure as heck, that was the problem.
My tableView was displaying the sorted_rows array in the View while segueing to
my_sections[indexPath.section].rows[indexPath.row]
instead of my_section[indexPath.section].sorted_rows[indexPath.row]
Problem solved. Silly mistake. Thanks again to everyone who helped me simplify my code.

Create and perform segue without storyboards

i got an app without storyboards, all UI creation is made in code and I got a splitView which I would make it usable on iPhone, because as the app as been first designed for iPad only, so that when you select a row in the list in the Master view it does nothing on iPhone but is working fine on iPad.
So my question is can I create and perform the segue that allows to show the Detail View on the didSelectRowAtIndexPath method ?
Here's what i've done so far :
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let segue = UIStoryboardSegue(identifier: "test", source: self, destination: detailViewController!)
performSegueWithIdentifier("test", sender: self)
}
but when running and selecting a row the app was crashing telling it needed a performhandler so i added this :
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let segue = UIStoryboardSegue(identifier: "test", source: self, destination: detailViewController!, performHandler: { () -> Void in
let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
let controller = self.detailViewController!
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
})
performSegueWithIdentifier("test", sender: self)
}
and now when selecting a row xcode says that there is no segue with such identifier "test".
I also tried to call it by segue.perform() and add the performHandler content into the prepareForSegueMethod :
if segue.identifier == "test" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let object = self.fetchedResultsController.objectAtIndexPath(indexPath)
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
and it does just nothing, doesn't crash, just highlight the row i selected and that's all
Can you guys help me ?
EDIT : As Oleg Gordiichuk said, it's not possible to do what I want to do without Storyboards, so thanks for his help :)
Segue it is component of the storyboard interaction it is possible to understand from name of the class UIStoryboardSegue. It is bad idea to create segues programmatically. If i am not making mistake storyboard creates them for you.
For solving of you're issue try to use some common ways like simply present ViewController.
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("id") as! MyController
self.presentViewController(vc, animated: true, completion: nil)
As i understand from our conversation in comments. You would like to create navigation for tableview to details view using segues without storyboard. For now it is impossible to do this without storyboard.
For future learning try to investigate this information.
One way is to use the didSelectRow method for tableView
Swift 3.x
// MARK: - Navigation & Pass Data
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Selected Row \(indexPath.row)")
let nextVC = YourNextViewController()
nextVC.YourLabel.text = "Passed Text"
nextVC.YourLabel.text = YourArray[indexPath.row]
// Push to next view
navigationController?.pushViewController(nextVC, animated: true)
}

Delay or error performing segue from TableView

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.

Push segue from UITableViewCell to ViewController in Swift

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.

Send info and reload page from another view controller without segue in swift

I have a tableView(top) and a view controller(bottom) within container views in the same view. I need to send info and refresh the bottom view when selecting a table row. I'd like it to work like the apple stocks app. I originally had the bottom view on another page and used a segue and it worked great. But I'm not sure how to do it without a segue now.
Here is the code for selecting the row:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
let item = items[indexPath.row]
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
What I had before for the segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let controller = segue.destinationViewController as SNPDetailViewController
if let indexPath = tableView.indexPathForCell(sender as UITableViewCell) {
controller.itemToEdit = items[indexPath.row]
}
}
And what was working when I used the segue in the (now) bottom view:
override func viewDidLoad() {
super.viewDidLoad()
if let item = itemToEdit {
title = item.name
snpDetails.text = item.details
}
}
Any help is greatly appreciated!
In your table view controller, self.parentViewController will point to the container view controller. Then you can get a reference to the existing detail view controller via the childViewControllers property of the container:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
let item = items[indexPath.row]
if let vc = self.parentViewController {
let siblings = vc.childViewControllers
if siblings.count > 1 {
if let detailVC = siblings[1] as? SNPDetailViewController {
detailVC.itemToEdit = item
} else {
println("Odd, that detail view controller is not the right class")
abort()
}
} else {
println("Odd, there is no detail view controller")
abort()
}
} else {
println("Strange, I'm not embedded in a parent view controller")
abort()
}
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
This assumes your table view controller is at index 0 of childViewControllers, and the detail view controller is at index 1. Amend siblings[1] to siblings[0] if it's the other way around.
You may need to implement a setter method for itemToEdit in order to reload the labels etc when the value changes.
I guess your bottom view is SNPDetailViewController
As you can see in your previous code you had a variable called controller. That variable is missing in your actual code. Try to create it in your first snippet of code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
let item = items[indexPath.row]
}
let controller = SNPDetailViewController()
// then you can call the _itemToEdit_ method in your other view
if let indexPath = tableView.indexPathForCell(sender as UITableViewCell) {
controller.itemToEdit = items[indexPath.row]
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
I'm not completely sure if that works but the idea is that you need like an instance of your bottom view to access its methods. Let me know if that helps.

Resources