将数据从数组加载到UITableView单元中

时间:2019-04-04 22:23:30

标签: ios swift xcode uitableview

我对快速编程和尝试构建一个可以接受订单并将其转发给管理员应用程序的应用程序非常陌生。我的数据没有加载到UITableView中,我不确定为什么,据我所知,我已经完成了本书的所有工作。我正在从我创建的节点服务器中加载数据,并且在打印数组的内容时,所有项目均作为键,对值打印。 UIimages正在每个tableView单元中加载,但标签未加载,并且在设置标签并打印它们之后,值仍为标签的零。

我创建了一个名为PizzaListTableViewController的TableView类和一个名为class的自定义TableViewCell PizzaTableViewCell。我在情节提要界面构建器中添加了一个UIimage和三个标签。

  

结构为:ViewController> TableView> TableViewCell>图像,标签

我的主VC已连接到其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?.textcell.amount?.textcell.miscellaneousText?.text的值显示为空。

1 个答案:

答案 0 :(得分:0)

请尝试在作为参数传递给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)
    }

请避免从后台线程执行UI工作,因为它不正确/不安全。同样,您也可以尝试在该主线程块内设置self..pizza。 并请考虑艾伦(Alan)在两次通话时的建议。

  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

}