Проблема загрузки данных из массива в ячейки UITableView - PullRequest
2 голосов
/ 05 апреля 2019

Я очень новичок в быстром программировании и пытаюсь создать приложение, которое будет принимать заказы и передавать их в приложение администратора.Мои данные не загружаются в мой UITableView, и я не уверен, почему, насколько я могу судить, я сделал все по книге.Я загружаю данные с созданного мной сервера узлов, и при печати содержимого массива все элементы печатаются как ключевые, парные значения.UIimages загружаются в каждую из ячеек tableView, а метки - нет, и после установки и печати меток значения по-прежнему равны нулю.

Я создал класс TableView с именем PizzaListTableViewController и пользовательский TableViewCell class с именем PizzaTableViewCell.Я добавил UIimage и три метки в конструкторе интерфейса раскадровки.

Структура: ViewController> TableView> TableViewCell> Изображение, метки

Мой главный виртуальный канал подключен кего ViewController.class Мой TableViewCell подключен к его TableViewCell.class. У меня есть идентификатор и он связан с ним, как показано в коде ниже, я связал все выходы.Любая помощь будет принята с благодарностью!

Я пытался переписать классы, разорвать все розетки и заново подключить их, назначить значения в методе, в котором установлены метки, но ничего не получилось.

class PizzaListTableViewController: UITableViewController {
    var pizzas: [Pizza] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        //title you will see on the app screen at the top of the table view
        navigationItem.title = "Drink Selection"

        //tableView.estimatedRowHeight = 134
        //tableView.rowHeight = UITableViewAutomaticDimension

        fetchInventory { pizzas in
            guard pizzas != nil else { return }
            self.pizzas = pizzas!
            //print(self.pizzas)
            self.tableView.reloadData()
            //print(self.pizzas)
        }


    }   //end of viewDidLoad

    private func fetchInventory(completion: @escaping ([Pizza]?) -> 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 -> Pizza? in
                    var data = pizzaDict!
                    data["image"] = UIImage(named: pizzaDict!["image"] as! String)

                    //print(data)
                    //print("CHECK")
                    print("Printing all data: ", Pizza(data: data))
                    //printing all inventory successful


                    return Pizza(data: data)
                }
                //self.tableView.reloadData()
                completion(inventory)
        }
    }

    @IBAction func ordersButtonPressed(_ sender: Any) {
        performSegue(withIdentifier: "orders", sender: nil)
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    //PRINTING ROWS 0 TWICE in console
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //print("ROWS", pizzas.count)
        return self.pizzas.count
    }


    //THIS IS WHERE THE CELL IDENTIFIER IS ??
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //print("IN CELLFORROWAT")

        tableView.register(PizzaTableViewCell.self, forCellReuseIdentifier: "cell")

        let cell: PizzaTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PizzaTableViewCell

        //cell.backgroundColor = Services.baseColor

        cell.name?.text = pizzas[indexPath.row].name
        cell.imageView?.image = pizzas[indexPath.row].image
        cell.amount?.text = "$\(pizzas[indexPath.row].amount)"
        cell.miscellaneousText?.text = pizzas[indexPath.row].description

        print(cell.name?.text! as Any)
        print(cell.imageView as Any)
        //print("END CELLFORROWAT")

        return cell
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100.0
    }  //END OF

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "pizza", sender: self.pizzas[indexPath.row] as Pizza)
    }  //END OF override func tableView

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "pizza" {
            guard let vc = segue.destination as? PizzaViewController else { return }
            vc.pizza = sender as? Pizza
        }
    }  //END OF override preppare func

}
class PizzaTableViewCell: UITableViewCell {

    @IBOutlet weak var name: UILabel!
    @IBOutlet weak var pizzaImageView: UIImageView!
    @IBOutlet weak var amount: UILabel!

    @IBOutlet weak var miscellaneousText: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

         //Configure the view for the selected state
    }

}
struct Pizza {
    let id: String
    let name: String
    let description: String
    let amount: Float
    let image: UIImage

    init(data: [String: Any]) {

        //print("CHECK:: pizza.swift")

        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
    }

}

Я также напечатал значения массива на консоль, и данные печатаются, как и ожидалось, но значения cell.name?.text, cell.amount?.text и cell.miscellaneousText?.text print nil.

1 Ответ

0 голосов
/ 05 апреля 2019

Пожалуйста, попробуйте перезагрузить ваш просмотр таблицы в главном потоке внутри кода, который вы передаете в качестве параметра в fetchInventory:

DispatchQueue.main.async { 
    self.tableView.reloadData()
}

Итак, ваш вызов fetchInventory должен выглядеть так:

    fetchInventory { pizzas in
        guard pizzas != nil else { return }
        self.pizzas = pizzas!
        //print(self.pizzas)
        DispatchQueue.main.async { 
            self.tableView.reloadData()
        }
        //print(self.pizzas)
    }

Пожалуйста, избегайте работы пользовательского интерфейса из фонового потока, потому что это не правильно / безопасно.Также вы можете попытаться установить self? .Pizzas внутри этого основного потока.И, пожалуйста, примите во внимание совет Алана о двойном вызове.

  1. Пожалуйста, полностью удалите регистр из tableView / cellForRow.

    // tableView.register(PizzaTableViewCell.self, forCellReuseIdentifier: "cell")
    
  2. Вместо:

    cell.imageView?.image = pizzas[indexPath.row].image
    

    поставить:

    cell.pizzaImageView?.image = pizzas[indexPath.row].image
    

Это название вашей торговой точки.

Пожалуйста, проверьте мой тест ниже, который работает enter image description here:

import UIKit

класс PizzaListTableViewController: UITableViewController {

var pizzas: [Pizza] = []

override func viewDidLoad() {
    super.viewDidLoad()
    //title you will see on the app screen at the top of the table view
    navigationItem.title = "Drink Selection"

    //tableView.estimatedRowHeight = 134
    //tableView.rowHeight = UITableViewAutomaticDimension

    fetchInventory { pizzas in
        guard pizzas != nil else { return }
        self.pizzas = pizzas!
        print(self.pizzas)
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
        //print(self.pizzas)
    }
}   //end of viewDidLoad

private func fetchInventory(completion: @escaping ([Pizza]?) -> Void) {
    let rawInventory0 = [
        [
            "id": "1",
            "name": "name1",
            "amount": 1234,
            "description": "description1",
            "image": "image1"
        ],
        [
            "id": "2",
            "name": "name2",
            "amount": 1235,
            "description": "description2",
            "image": "image2"
        ],
        [
            "id": "3",
            "name": "name3",
            "amount": 1236,
            "description": "description3",
            "image": "image3"
        ],
        [
            "id": "4",
            "name": "name4",
            "amount": 1237,
            "description": "description4",
            "image": "image4"
        ]
    ]  as? [[String: Any]?]
    guard let rawInventory1 = rawInventory0 as? [[String: Any]?] else { return completion(nil) }
    let inventory = rawInventory1.compactMap { pizzaDict -> Pizza? in
        var data = pizzaDict!
        data["image"] = UIImage(named: pizzaDict!["image"] as! String)
        print(data)
        print("CHECK")
        print("Printing all data: ", Pizza(data: data))
        //printing all inventory successful
        return Pizza(data: data)
    }
    //self.tableView.reloadData()
    completion(inventory)
}

// MARK: - Table view data source

@IBAction func ordersButtonPressed(_ sender: Any) {
    performSegue(withIdentifier: "orders", sender: nil)
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

//PRINTING ROWS 0 TWICE in console
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //print("ROWS", pizzas.count)
    return self.pizzas.count
}


//THIS IS WHERE THE CELL IDENTIFIER IS ??
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //print("IN CELLFORROWAT")

    // tableView.register(PizzaTableViewCell.self, forCellReuseIdentifier: "cell")

    let cell: PizzaTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PizzaTableViewCell

    //cell.backgroundColor = Services.baseColor

    cell.name?.text = pizzas[indexPath.row].name
    cell.pizzaImageView?.image = pizzas[indexPath.row].image
    cell.amount?.text = "\(pizzas[indexPath.row].amount)"
    cell.miscellaneousText?.text = pizzas[indexPath.row].description

    print(cell.name?.text! as Any)
    //print(cell.imageView as Any)
    //print("END CELLFORROWAT")

    return cell
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 100.0
}  //END OF

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    performSegue(withIdentifier: "pizza", sender: self.pizzas[indexPath.row] as Pizza)
}  //END OF override func tableView

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "pizza" {
        guard let vc = segue.destination as? PizzaViewController else { return }
        vc.pizza = sender as? Pizza
    }
}  //END OF override preppare func

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...