我在cellForRowAt遇到错误,我不确定为什么

时间:2019-11-25 05:57:07

标签: ios swift swift4 swift5

THIS IS WHAT I WANT IT TO LOOK LIKE我在cellForRowAt函数中遇到错误,我不确定为什么错误显示为“

  

无法将类型“产品”的值分配为类型“字符串?”。它在此行cell.textLabel?.text = product

处给了我错误

有人知道我的代码有什么问题吗?我正在尝试在一个UITableView列中显示三个不同的字符串,因此它们会在这样的“ Item Price SalePrice”列中显示

import UIKit

let defaults = UserDefaults(suiteName: "com.Saving.Data")
struct Product: Codable {
    var item: String
    var price: String
    var salesPrice: String
}
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() {
        defaults?.set(items, forKey: "savedData")
        defaults?.synchronize()
    }

    func getData() {
        if let data = UserDefaults.standard.data(forKey: "savedData") {
            do {
                items = try PropertyListDecoder().decode([Product].self, from: data)
                print(items)
                tableView.reloadData()
            } catch { print(error) }
        }
    }



}

    //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

        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()
    }
}

4 个答案:

答案 0 :(得分:1)

cell.textLabel?.text = product  尝试做product.itemproduct.priceproduct.salesPrice.

cell.textLabel?.text期望您设置的字符串是另一种类型。

答案 1 :(得分:1)

cell.textLabel?.text只能显示String对象,而不能显示其他对象。

它将是product.itemproduct.priceproduct.salesPrice或全部一行。 (根据您的要求)。

确保product的值不为零。

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

您可以尝试的完整代码:

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")
    }
}

答案 2 :(得分:0)

首先重用单元格。

永远不要使用默认的初始化程序创建单元格。

在Interface Builder中为单元格分配一个标识符(例如Health()),然后替换

package main
import "errors"

// IAdapter - Reduced to one function to make this simple
type IAdapter interface {
    Adapter_descriptor() error
}

/// NewRequestHandlerProxy - Simplified version of the New function
func NewRequestHandlerProxy(iadapter IAdapter) {
    return // code removed to make example simple
}

// adaptImpl - Implements the IAdapter interface
type adaptImpl struct {
    isError bool // example only
}

// Adapter_descriptor - Implement the function specified in the interface
func (a adaptImpl) Adapter_descriptor() error {
    if a.IsError {
        return errors.New("An error happened")
    }
    return nil
}

func main() {
    // Create an adaptImpl which implements IAdapter 
    x := adaptImpl{isError: true}
    NewRequestHandlerProxy(x)
}

使用

MainCell

错误非常清楚。如在其他答案中已经提到的,您必须将let cell = UITableViewCell() 属性的值分配给标签

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

答案 3 :(得分:0)

不要使用默认的初始化程序创建单元格

在界面构建器中为表视图的单元格分配一个标识符

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

您必须将Product的属性分配给标签的文本

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
    }