Reputation: 339
I have a TableView that when the user clicks it needs to show a detail view displaying the name of the row it clicked. I populate the tableView using a Json call but I can't figure out what I'm doing wrong.
This is my bits of code of ViewController
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var valueToPass:String!
@IBOutlet weak var tableView: UITableView!
// Instantiate animals class
var items = [animalObject]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
addDummyData()
}
func addDummyData() {
RestManager.sharedInstance.getRandomUser(onCompletion: {(json) in
if let results = json.array {
for entry in results {
self.items.append(animalObject(json: entry))
}
DispatchQueue.main.sync{
self.tableView.reloadData()
}
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") as! CustomTableViewCell!
let animal = self.items[indexPath.row]
cell?.label.text = animal.name
return cell! //4.
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
// let indexPath = tableView.indexPathForSelectedRow!
var currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
print(currentCell.textLabel?.text)
valueToPass = currentCell.textLabel?.text
print(valueToPass)
performSegue(withIdentifier: "detailView", sender: indexPath)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "detailView") {
// initialize new view controller and cast it as your view controller
let viewController = segue.destination as! DetailViewController
// your new view controller should have property that will store passed value
viewController.passedValue = valueToPass
}
}
}
and my detailView only has the following info
@IBOutlet weak var tooPass: UILabel!
var passedValue: String!
override func viewDidLoad() {
super.viewDidLoad()
print("DETAILS")
print(passedValue)
tooPass.text = passedValue
}
I'm not sure if the preparedToSegue is firing a little bit earlier because my terminal looks like this:
I used as a reference the following question any guidance will be appreciated
Upvotes: 0
Views: 55
Reputation: 521
Good approach here is to use view model. Create model which contains your items and data associated with them. And at segue pass your data model. It’s bad coding, getting data right from cell on didSelect method, unless some ui working on that cell
Upvotes: 0
Reputation: 1586
Try this for didSelectRowAt
method.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
valueToPass = self.items[indexPath.row]
print(valueToPass)
performSegue(withIdentifier: "detailView", sender: indexPath)
}
Just pass the entire item in the items array.
Make the DetailViewController's passed item of type item. Then just access item.whateverPropertyRequired
.
Upvotes: 1
Reputation: 3802
The problem is that in your cellForRow
method, you are casting your cell to CustomTableViewCell
type while in your didSelectRow
, you are casting it as UITableViewCell
. Change
var currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
in your didSelectRow
to
var currentCell = tableView.cellForRow(at: indexPath)! as CustomTableViewCell
Upvotes: 0