I am new to swift programming and running into errors with performing a segue from a tableview cell when it is pressed to a view controller giving details about that cell. The error I am getting is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'Receiver (<DrinkupClient.DrinkListTableViewController: 0x7fec5d431510>)
has no segue with identifier 'pizzaSegue''
I have already tried the following: 1) Tried renaming the storyboard and make sure to set the main storyboard in the project settings and in the info.plist file (Key is 'Main storyboard file base name'). I currently have the storyboard named: "Main.storyboard"
2) Tried doing a clean of the product (Product -> Clean) and rebuild but this gives same error
3) I have tried deleting the app from the simulator and running it again
4) I have double checked and the segue identifier in interface builder is called "pizzaSegue" and it is the same in my code.
import UIKit
import Alamofire
struct Drink {
let id: String
let name: String
let description: String
let amount: Float
let image: UIImage
init(data: [String: Any]) {
self.id = data["id"] as! String
self.name = data["name"] as! String
//self.amount = data["amount"] as! Float
self.amount = ((data["amount"] as? NSNumber)?.floatValue)!
self.description = data["description"] as! String
self.image = data["image"] as! UIImage
}
}
class DrinkTableViewCell: UITableViewCell {
@IBOutlet weak var cellName: UILabel!
@IBOutlet weak var cellAmount: UILabel!
@IBOutlet weak var cellDescription: UILabel!
@IBOutlet weak var cellImage: UIImageView!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class DrinkListTableViewController: UITableViewController {
var drinks: [Drink] = []
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Drink Selection"
tableView.dataSource = self
tableView.delegate = self
//tableView.register(DrinkTableViewCell.self, forCellReuseIdentifier: "cell")
tableView.register(DrinkTableViewCell.self as AnyClass, forCellReuseIdentifier: "cell")
//tableView.register(UINib(nibName: "DrinkTableViewCell", bundle: Bundle.main), forCellReuseIdentifier: "cell")
//tableView.estimatedRowHeight = 134
//tableView.rowHeight = UITableView.automaticDimension
fetchInventory { drinks in
guard drinks != nil else { return }
self.drinks = drinks!
//print("Data from API call: ", self.drinks)
//self.tableView.reloadData()
// DispatchQueue.main.async { [weak self] in
// self?.tableView.reloadData()
// }
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.async { [weak self] in
self?.tableView.reloadData()
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "pizzaSegue", sender: self.drinks[indexPath.row] as Drink)
//trying another method below?
//self.navigationController?.pushViewController(UIViewController() as! PizzaViewController, animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "pizzaSegue" {
guard let vc = segue.destination as? PizzaViewController else { return }
vc.pizza = sender as? Pizza
}
}
private func fetchInventory(completion: @escaping ([Drink]?) -> Void) {
Alamofire.request("http://127.0.0.1:4000/inventory", method: .get)
.validate()
.responseJSON { response in
guard response.result.isSuccess else { return completion(nil) }
guard let rawInventory = response.result.value as? [[String: Any]?] else { return completion(nil) }
let inventory = rawInventory.compactMap { pizzaDict -> Drink? in
var data = pizzaDict!
data["image"] = UIImage(named: pizzaDict!["image"] as! String)
//print("Printing each item: ", Drink(data: data))
//printing all inventory successful
return Drink(data: data)
}
completion(inventory)
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("ROWS: ", drinks.count)
return drinks.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DrinkTableViewCell
//let cell = UITableViewCell(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "cell")
let cell:DrinkTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! DrinkTableViewCell
//cell.cellName?.text = drinks[indexPath.row].name
//cell.cellAmount?.text = String(drinks[indexPath.row].amount)
//cell.cellDescription?.text = drinks[indexPath.row].description
//cell.cellImage?.image = drinks[indexPath.row].image
cell.imageView?.image = drinks[indexPath.row].image
cell.textLabel?.text = drinks[indexPath.row].name
cell.detailTextLabel?.text = drinks[indexPath.row].description
//print(cell.textLabel?.text)
//print(cell.detailTextLabel?.text)
print(cell.cellName?.text as Any)
//print(cell.cellImage?.image)
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.0
}
}
From your comment:
. I have a button in the tabBarController that presents the tableView and this is working fine.
let drinkController = DrinkListTableViewController()
let drinkNavigationController = UINavigationController(rootViewController: drinkController)
self.present(drinkNavigationController, animated: true, completion: nil)
No it isn't working fine. It is the problem.
Basically this is the same situation as in my answer here:
https://stackoverflow.com/a/40077530/341994
You are obtaining a useless instance when you say DrinkListTableViewController()
. What you need to do is talk to the storyboard and ask it to instantiate the desired view controller (by identifier) so that you get the instance from the storyboard, the one that has the segue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.