简体   繁体   中英

Im getting an error at cellForRowAt and im not sure why

I am getting an error in the function cellForRowAt

Cannot assign value of type 'Product' to type 'String?'

Is cell.textLabel?.text = product the issue that's causing this error?

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let product = items[indexPath.row]
        cell.textLabel?.text = product

        cell.contentView.backgroundColor = UIColor(red:0.92, green:0.92, blue:0.92, alpha:1.0)
        cell.textLabel?.textColor = UIColor(red:0.13, green:0.13, blue:0.13, alpha:1.0)
        tableView.separatorColor = UIColor(red:0.13, green:0.13, blue:0.13, alpha:1.0)


        return cell
    }

cell.textLabel?.text = product try doing product.item or product.price or product.salesPrice.

cell.textLabel?.text is expecting a string what you are setting is another type.

cell.textLabel?.text can only show a String object, not other objects.

It will be product.item or product.price or product.salesPrice or all in one line. (based on your requirement).

Make sure the value of product is not nil.

cell.textLabel?.text = "\(product.item) \(product.price) \(product.salesPrice)"

The full code you can try this:

class ViewController: UIViewController, UIAdaptivePresentationControllerDelegate {

    @IBOutlet weak var tableView: UITableView!

    var items:[Product]? = []

    // VIEW LOAD
    override func viewDidLoad() {
        super.viewDidLoad()

        if #available(iOS 13.0, *) {
            self.isModalInPresentation = true
        }

        getData()
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        getData()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(true)
        storeData()
    }
    override var prefersStatusBarHidden: Bool {
        return true
    }
    // ADD ITEMS
    @IBAction func addButtonTapped(_ sender: Any) {
        let alert = UIAlertController(title: "Product Information", message: nil, preferredStyle: .alert)
        alert.addTextField { (itemTextField) in
            itemTextField.placeholder = "Item"
        }
        alert.addTextField { (priceTextField) in
            priceTextField.placeholder = "Price"
        }

        alert.addTextField { (salePriceTextField) in
            salePriceTextField.placeholder = "Sale Price"
        }

        let action = UIAlertAction(title: "Add", style: .default) { (_) in
            let item = alert.textFields?[0].text ?? ""
            let price = alert.textFields?[1].text ?? ""
            let salesPrice = alert.textFields?[2].text ?? ""

            let product = Product(item: item, price: price, salesPrice: salesPrice)
            self.addProduct(product)
        }

        alert.addAction(action)
        present(alert, animated: true)
        storeData()

    }

    func addProduct(_ product: Product) {
        let index = 0
        items?.insert(product, at: index)

        let indexPath = IndexPath(row: index, section: 0)
        tableView.insertRows(at: [indexPath], with: .left)
        storeData()
    }

    //STORE DATA
    func storeData() {
        UserDefaultUtil.saveData(products: items)
    }

    func getData() {
        items = UserDefaultUtil.loadProducts()

    }

}

//EXTENSION
extension ViewController: UITableViewDataSource {
    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 = UITableViewCell()
        let product = items![indexPath.row]
        cell.textLabel?.text = "\(product.item!) \(product.price) \(product.salesPrice)"

        cell.contentView.backgroundColor = UIColor(red:0.92, green:0.92, blue:0.92, alpha:1.0)
        cell.textLabel?.textColor = UIColor(red:0.13, green:0.13, blue:0.13, alpha:1.0)
        tableView.separatorColor = UIColor(red:0.13, green:0.13, blue:0.13, alpha:1.0)


        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        guard editingStyle == .delete else { return }
        items?.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)
        storeData()
    }
}

class UserDefaultUtil {

    private static let Key = "savedData"

    private static func archivePeople(people : [Product]) -> NSData {

        return NSKeyedArchiver.archivedData(withRootObject: people as NSArray) as NSData
    }

    static func loadProducts() -> [Product]? {

        if let unarchivedObject = UserDefaults.standard.object(forKey: Key) as? Data {

            return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [Product]
        }

        return nil
    }

    static func saveData(products : [Product]?) {
        let archivedObject = archivePeople(people: products!)
        UserDefaults.standard.set(archivedObject, forKey: Key)
        UserDefaults.standard.synchronize()
    }

}

class Product: NSObject, NSCoding {
    var item: String?
    var price: String?
    var salesPrice: String?

    required init(item:String, price:String, salesPrice: String) {
        self.item = item
        self.price = price
        self.salesPrice = salesPrice
    }

    required init(coder aDecoder: NSCoder) {
        self.item = aDecoder.decodeObject(forKey: "item") as? String
        self.price = aDecoder.decodeObject(forKey: "price") as? String
        self.salesPrice = aDecoder.decodeObject(forKey: "salesPrice") as? String
    }

    public func encode(with aCoder: NSCoder) {
        aCoder.encode(item, forKey: "item")
        aCoder.encode(price, forKey: "price")
        aCoder.encode(salesPrice, forKey: "salesPrice")
    }
}

First of all reuse cells.

Never create cells with the default initializer.

Assign an identifier to the cell in Interface Builder (for example MainCell ), then replace

let cell = UITableViewCell()

with

let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for: indexPath)

The error is very clear. As already mentioned in other answers you have to assign the value of a property of Product to the label

cell.textLabel?.text = product.title

Don't create cells with default initializer

Assign an identifier to the tableview's cell in interface builder

let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

you have to assign the property of Product to label's text

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let product = items[indexPath.row]
        cell.textLabel?.text = product.price // product.item, product.salesPrice
        return cell
    }

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