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