UITableView Subclass

I have an app with a single view controller that contains multiple tables. I am trying to subclass the cell where the (tableView.tag == 2), but the IBOutlet is always nil and crashes the app. I have posted the code below if you can offer any suggestions. I have double checked the storyboard to make sure all connections and references are correct. I thought it maybe my withidentfier reference as all tables have an ID of “Cell”? Thanks in advance for any help!

image

//---------------------
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) → UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “Cell”, for: indexPath)

    if (tableView.tag == 1) {
        if hasSorted == true {
            let item = estimateCategoryResults[indexPath.row]
            configureEstimateText(for: cell, with: item)
        } else if isFiltering() {
            let item = estimateSearchResults[indexPath.row]
            configureEstimateText(for: cell, with: item)
        } else {
            let item = dataModel.estimateLists[indexPath.row]
            configureEstimateText(for: cell, with: item)
        }
        cell.accessoryType = .detailDisclosureButton
    } else if (tableView.tag == 2) {
        if hasSorted == true {
            let item = categoryResults[indexPath.row]
            configureTakeOffText(for: cell, with: item)
        } else if isFiltering() {
            let item = searchResults[indexPath.row]
            configureTakeOffText(for: cell, with: item)
        } else {
            //let item = currentEstimate.takeOffList[indexPath.row]
            let item = takeOffReference[indexPath.row] //10/27
            configureTakeOffText(for: cell, with: item)
        }
        cell.accessoryType = .detailDisclosureButton
    } else if (tableView.tag == 3) {
        if hasSorted == true {
            let item = categoryResults[indexPath.row]
            configureWarehouseText(for: cell, with: item)
        } else if isFiltering() {
            let item = searchResults[indexPath.row]
            configureWarehouseText(for: cell, with: item)
        } else {
            let item = dataModel.savedTakeOffList[indexPath.row]
            configureWarehouseText(for: cell, with: item)
        }
    }
    return cell
 }

//---------------------
func configureTakeOffText(for cell: UITableViewCell, with item: TakeOffItem) {
if let myCell = cell as? TakeOffItemTableViewCell {
print(“my cell”, myCell)
myCell.toCategoryLabel.text = “testing”
}
}

//---------------------
class TakeOffItemTableViewCell: UITableViewCell {

@IBOutlet var toCategoryLabel: 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
}

}

Hi @jport1130,
This is one of the most common stumbling block when devs use multiple tables on the same viewController.
A way that works well is to have a separate class for each table than check for a tag on the tableview.

cheers,

Hi Jayant,

Thank you for your response. I think I have completed what you recommended, but I am still having the same issue. Below I have included my “cellForRowAt” code for your review. Please let me know if you have any other suggestions.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    switch tableView.tag {
    case 1:
        print("i am table one")
        let cell = tableView.dequeueReusableCell(withIdentifier: "EstimateCell", for: indexPath)
        
                    if hasSorted == true {
                        let item = estimateCategoryResults[indexPath.row]
                        configureEstimateText(for: cell, with: item)
                    } else if isFiltering() {
                        let item = estimateSearchResults[indexPath.row]
                        configureEstimateText(for: cell, with: item)
                    } else {
                        let item = dataModel.estimateLists[indexPath.row]
                        configureEstimateText(for: cell, with: item)
                    }
                    cell.accessoryType = .detailDisclosureButton
        
        return cell

    case 2:
        print("i am table two")
        let cell = tableView.dequeueReusableCell(withIdentifier: "TakeOffCell", for: indexPath)
        
                    if hasSorted == true {
                        let item = categoryResults[indexPath.row]
                        configureTakeOffText(for: cell, with: item)
                    } else if isFiltering() {
                        let item = searchResults[indexPath.row]
                        configureTakeOffText(for: cell, with: item)
                    } else {
                        //let item = currentEstimate.takeOffList[indexPath.row]
                        let item = takeOffReference[indexPath.row] //10/27
                        configureTakeOffText(for: cell, with: item)
                        
                    }
        cell.accessoryType = .detailDisclosureButton
        
        return cell

    case 3:
        print("i am table three")
        let cell = tableView.dequeueReusableCell(withIdentifier: "WarehouseCell", for: indexPath)
        
                    if hasSorted == true {
                        let item = categoryResults[indexPath.row]
                        configureWarehouseText(for: cell, with: item)
                    } else if isFiltering() {
                        let item = searchResults[indexPath.row]
                        configureWarehouseText(for: cell, with: item)
                    } else {
                        let item = dataModel.savedTakeOffList[indexPath.row]
                        configureWarehouseText(for: cell, with: item)
                    }
        
        return cell

    default:
        print("i am not a table")
    }

//--------------------------------------------------------------------------------------------
func configureTakeOffText(for cell: UITableViewCell, with item: TakeOffItem) {

    if let myCell = cell as? TakeOffItemTableViewCell {
        myCell.toCategoryLabel.text = item.toCategory
    }

Hi @jport1130,
Have you tried to explicitly cast the cell as your subclassed cell rather than the generic UITableViewCell?

The generic UITableViewCell does not have a member called toCategoryLabel

cheers,

Jayant

Hi Jayant,

I have tried this and now am receiving the following error. Thanks

‘NSInternalInconsistencyException’, reason: ‘unable to dequeue a cell with identifier TakeOffCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard’

Hi @jport1130,
That is one step ahead than where you were before.

How are you creating your table and the cells? in NIB files or storyboard? This error indicates that you are using a NIB or a cell that is not associated with the tableview you are attempting to use.

You need to register the tableCells with the table before using.

cheers,

I am using storyboard. I did some research about registering so I will give that a try.

Thanks.

This topic was automatically closed after 166 days. New replies are no longer allowed.