1

I have an enum with several cases that I'm using for calculations and the user will be able to set one as their preference. They of course need to be able to change that preference so I want to show these in a table view so they can see them all and choose the one they want to set as their preference.

enum Calculation: Int {

    case Calculation1

    case Calculation2

    case Calculation3

    case Calculation4

    case Calculation5

    case Calculation6

    case NoChoice // this exist only for the little trick in the refresh() method for which I need to know the number of cases

    // This static method is from http://stackoverflow.com/questions/27094878/how-do-i-get-the-count-of-a-swift-enum/32063267#32063267
static let count: Int = {
    var max: Int = 0
    while let _ = Calculation(rawValue: max) { max += 1 }
    return max
    }()

    static var selectedChoice: String {
        get {
            let userDefaults = NSUserDefaults.standardUserDefaults().objectForKey("selectedCalculation")
            if let returnValue = userDefaults!.objectForKey("selectedCalculation") as? String { 
                return returnValue // if one exists, return it
            } else {
        return "Calculation1" // if not, return this default value
    }
  }
    set {
        NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "selectedCalculation")
        NSUserDefaults.standardUserDefaults().synchronize()
    }
  }
 }

The problem is that an enum doesn't have an indexPath so I can't iterate through it and grab those case names:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("formulaCell", forIndexPath: indexPath)

    // Configure the cell...
    let currentFormula = Calculation[indexPath.row] <- Error: Type 'Calculation.Type' has no subscript members
    cell.textLabel?.text = currentFormula
    return cell
}

The best I could come up with is to create an array of those cases and use it to create the cells:

let Calculation = [Calculation1, Calculation2, Calculation3 ...etc] 

which worked but is clearly an ugly hack.

Is there a better way to do this?

Jim
  • 1,260
  • 15
  • 37
  • Why would you do it this way and not use an `Array` of `Calculation` structs? – Fogmeister May 17 '16 at 14:11
  • 1
    The hack only seems ugly because you start of with a very bad and ugly way defining enum values by simply enumerating them. Whenever you enumerate some variables by their names there is something wrong. Give them meaningful names or use arrays in the first place. – luk2302 May 17 '16 at 14:12
  • why not use a switch statement to go through the different enum cases? – NSGangster May 17 '16 at 14:33
  • @ luk2302 Agreed. I just made the enum values generic for the purpose of posting this. I would never use names like that in the real world. – Jim May 17 '16 at 19:45

1 Answers1

0

use a switch statement on your enum to handle creating cell for each case.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("formulaCell", forIndexPath: indexPath)
    let calculation = Calculation(rawValue: indexPath.row + 1) //Start at 1 and add one.

    switch calculation {
        case .Calculation1:
             //Configure cell for case 1
        case .Calculation2
        //Configure cell for case 2 etc...
        default:
    }

    return cell
}
NSGangster
  • 2,397
  • 12
  • 22
  • Xcode doesn't like this: `let calculation = Calculation(rawValue: indexPath.row + 1)` It wants me to add a comma separator after indexPath.row. When I do that it complains "Can't invoke initializer for type 'Calculation' with an argument list type of '(rawValue: Int,_)' I tried adding this to my enum: `static var cases: Calculation = [Calculation1, Calculation2, Calculation3 ...etc] init(_ ix:Int) { self = Calculation.cases[ix] }` I then did this: ` let cellText = Formula.cases(rawValue: indexPath.row)` which doesn't work. – Jim May 17 '16 at 23:39