Back in the old Objective-C days I would often use enums for things like tables with constant contents, segmented controls, etc - in situations where there was an enforced incremented list of integers starting at zero. I would also often add a ...count member at the end to give a count of the entries, useful for table section & rows. Trying to do this with swift enums is proving troublesome - lots of conversions to & from raw values and extra default clauses in switches to allow for the 'count' entry. Can anyone suggest a graceful method of dealing with these sorts of situations?
            Asked
            
        
        
            Active
            
        
            Viewed 660 times
        
    2 Answers
2
            
            
        Automatic increment is still available in Swift.
enum Section: Int {
   case A = 0
   case B
   case C
}
Section.C.rawValue // -> 2
As for count, you should implement it manually (as How do I get the count of a Swift enum?):
enum Section: Int {
   case A = 0
   case B
   case C
   static let count = C.rawValue + 1
}
As for "conversions to & from raw values and extra default clauses" problem, compare with enum instead of its rawValue.
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return Section.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch Section(rawValue: section)! {
    case .A: return 1
    case .B: return 2
    case .C: return 5
    }
}
If you want to do something like array[Section.A], you can easily implement it.
extension Array {
    subscript(section: Section) -> T {
        return self[section.rawValue]
    }
}
extension NSIndexPath {
    convenience init(forRow row: Int, inSection section: Section) {
        self.init(forRow: row, inSection: section.rawValue)
    }
}
let array = ["foo", "bar", "baz"]
array[.B] // -> "bar"
let indexPath = NSIndexPath(forRow: 20, inSection: .C)
indexPath.section // -> 2
indexPath.row // -> 20
And so on.. :)
- 
                    Hard-coding the count - either as a literal or by referencing the (named) last element - are maintenance issues waiting to happen, the whole point of the ...count member was to automate this process. The best solution seems to be to add a 'count' computed value that iterates through integers from zero until it finds one that isn't a valid raw value. Which is clunky but usable. – Rev. Andy Jul 23 '15 at 15:50
 - 
                    You don't need to make `count` a computed value. for exmaple: `static let count: Int = { var i = 0; while Section(rawValue: i) != nil { i++ }; return i }()` works. – rintaro Jul 24 '15 at 07:30
 
0
            
            
        Add a function "count" to each enum. For example
static func count() -> Int { return 3 }
Integer -> enum conversion is done by the init method.
        gnasher729
        
- 51,477
 - 5
 - 75
 - 98