swiftxcodeindexpath

How to make IndexPath rawRepresentable?


I am trying to refactor code and create an enum class to hold indexPath of table view cells.

I would like to make the code works this way:

enum TableViewCell: IndexPath {
     case shopImageView = [0,0]
     case selectShopImageButton = [0,1]
}

But the compiler says indexPath is not rawRepresentable:

'TableViewCell' declares raw type 'IndexPath', but does not conform to RawRepresentable and conformance could not be synthesized

Raw value for enum case must be a literal

How can I make indexPath rawRepresentable? The code currently works like this and I would like to improve it.

enum TableViewCell {
    case shopImageView
    case selectShopImageButton
    case shopNameLocal
    case shopNameEN
    case addressLocal
    case addressEN
    case selectAddressButton
    case openingHours
    case datePickers
    case phone
    case email
    case uploadShopFormButton
    
    var indexPath: IndexPath {
        switch self {
        case .shopImageView:         return [0,0]
        case .selectShopImageButton: return [0,1]
        case .shopNameLocal:         return [0,2]
        case .shopNameEN:            return [0,3]
        case .addressLocal:          return [0,4]
        case .addressEN:             return [0,5]
        case .selectAddressButton:   return [0,6]
        case .openingHours:          return [0,7]
        case .datePickers:           return [0,8]
        case .phone:                 return [0,9]
        case .email:                 return [0,10]
        case .uploadShopFormButton:  return [0,11]
        }
    }
}

Solution

  • Another way of using hard coded TableView IndexPath's is to use an enum with static properties. The benefit of doing this is that if you reference the IndexPath's in various TableView delegate methods, and you need to change the IndexPath references, then you only have to change them once in the enum.

     private enum TableIndex {
        // Section 0: Information
        static let information =        IndexPath(row: 0, section: 0)
        // Section 1: Preferences
        static let notifications =      IndexPath(row: 0, section: 1)
        static let units =              IndexPath(row: 1, section: 1)
        static let hapticFeedback =     IndexPath(row: 2, section: 1)
        // Section 2: Links
        static let leaveReview =        IndexPath(row: 0, section: 2)
        static let support =            IndexPath(row: 1, section: 2)
        static let privacyPolicy =      IndexPath(row: 2, section: 2)
        static let disclaimer =         IndexPath(row: 3, section: 2)
    }
    

    and you can then reference them like this:

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        switch indexPath {
        case TableIndex.information:
            // do something
        case TableIndex.notifications:
            // do something
        case TableIndex.units:
            // do something
    
            // etc
    
        default:
            break
        }
    }