Omar Al-Eisa
Omar Al-Eisa

Reputation: 67

dequeue custom cells with multiple tableviews in one viewcontroller

I am trying to dequeue multiple tableviews with custom cells in the same view controller I keep getting the error (Value of type 'UITableViewCell?' has no member 'serviceChoiceAmount','serviceChoicePrice','serviceChoiceTitle','serviceChoiceImage') below I have the code for the view controller and one custom cell (same error will appear for others). (I have not input all the code for the other cells, if I have a solution to this error I will do so), should I create an initializer for the cell inside the custom cell class and dequeue using that inside the view controller?

View Controller

import UIKit

class CartViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {





let defaults = UserDefaults.standard
var TOTAL = [Double]()
@IBOutlet weak var cartTableView: UITableView!
@IBOutlet weak var totalTableView: UITableView!

@IBOutlet weak var optionsTableView: UITableView!
@IBOutlet weak var choosePayment: UITableViewCell!
@IBOutlet var address: [UITableViewCell]!


override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    let Cartcell = defaults.array(forKey: "Cart")
    print(Cartcell as Any)
    print(TOTAL)
    print("ViewDidLoad")
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func clearCart(_ sender: Any) {
    //add function to clear total cell
    CartSingleton1.sharedInstance.orderDict.removeAll()
    cartTableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
    var section: Int?
    if tableView == self.cartTableView{
        section = 1
    }
    if tableView == self.totalTableView{
        section = 1
    }
    if tableView == self.optionsTableView{
        section = 3
    }
    return section!
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    var title: String?
    if tableView == self.cartTableView{
        title = ("Order Details")
    }
    if tableView == self.totalTableView{
        title = ("Total")
    }
    if tableView == self.optionsTableView{
        title = ("Payment Option")
        //dropoff address
        //pickup address
    }
    return title!
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    var count: Int?
    if tableView == self.cartTableView{
    count = CartSingleton1.sharedInstance.orderDict.count
    }
    if tableView == self.totalTableView{
        count = 1
    }
    if tableView == self.optionsTableView{
        count = 3
    }
    return count!
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell: UITableViewCell?
    if tableView == self.cartTableView{
    let cart = CartSingleton1.sharedInstance.orderDict[indexPath.row] as NSDictionary
    cell = tableView.dequeueReusableCell(withIdentifier: "ServiceCart") as! CartTableViewCell
    cell.serviceChoiceImage.image = cart.value(forKey: "image") as? UIImage
    cell.serviceChoicePrice.text = cart.value(forKey: "pricing") as? String
    cell.serviceChoiceTitle.text = cart.value(forKey: "titled") as? String
    let quantityInt = cart.value(forKey: "quantity") as? Int
    cell.serviceChoiceAmount.text = quantityInt?.description
    }
    if tableView == self.totalTableView{

    }
    if tableView == self.optionsTableView{

    }
    return cell!
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if tableView == self.cartTableView{
    if editingStyle == .delete{
        print("deleted")

        CartSingleton1.sharedInstance.orderDict.remove(at: indexPath.row)
        self.cartTableView.deleteRows(at: [indexPath], with: .automatic)
        print("cart dictionary delete", CartSingleton1.sharedInstance.orderDict)
    }
    }
}
/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

custom cell: CartTableViewCell

import UIKit

class CartTableViewCell: UITableViewCell {

@IBOutlet weak var serviceChoiceImage: UIImageView!
@IBOutlet weak var serviceChoiceTitle: UILabel!
@IBOutlet weak var serviceChoiceAmount:UILabel!
@IBOutlet weak var serviceChoicePrice: UILabel!



override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

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

    // Configure the view for the selected state
}

}

Upvotes: 0

Views: 659

Answers (1)

vacawama
vacawama

Reputation: 154583

Your problem is that you have declared cell to be of type UITableViewCell? with this line:

var cell: UITableViewCell?

So, when you dequeue the cell and assign it to this variable, it assumes that type. So even though it is really a CartTableViewCell, Swift will only let you call methods and access properties that are available to UITableViewCell.

Get rid of that declaration and change your dequeue line to:

let cell = tableView.dequeueReusableCell(withIdentifier: "ServiceCart") as! CartTableViewCell

cell will then be of type CartTableViewCell and you'll be able to access its properties. Since cell is no longer optional, change your:

return cell!

to:

return cell

You will need to move this return into your if block, or assign the cell to another variable to return at the end of the function.


Alternatively, change cell to tableCell and use it only to return the cell value:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var tableCell: UITableViewCell?
    if tableView == self.cartTableView {
        let cart = CartSingleton1.sharedInstance.orderDict[indexPath.row] as NSDictionary
        let cell = tableView.dequeueReusableCell(withIdentifier: "ServiceCart") as! CartTableViewCell
        cell.serviceChoiceImage.image = cart.value(forKey: "image") as? UIImage
        cell.serviceChoicePrice.text = cart.value(forKey: "pricing") as? String
        cell.serviceChoiceTitle.text = cart.value(forKey: "titled") as? String
        let quantityInt = cart.value(forKey: "quantity") as? Int
        cell.serviceChoiceAmount.text = quantityInt?.description
        tableCell = cell
    }
    if tableView == self.totalTableView {

    }
    if tableView == self.optionsTableView {

    }
    // safely unwrap tableCell and return UITableViewCell() if nothing was assigned
    return tableCell ?? UITableViewCell()
}

Upvotes: 1

Related Questions