简体   繁体   中英

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver () has no segue with identifier 'pizzaSegue'

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
     }

}

屏幕截图显示控制台中的错误和故事板中的 segue 标识符

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM