The point of this protocol is to be able to quickly and easily get all the cases of an enum as well as the number of cases quickly and easily. This makes things like modelling UITableView
sections quick and easy.
Step 1: Conform your enum to RawIntInitable
. All you have to do is add the protocol. If your enum derives from type Int
, then you already conform. We just need to tell the compiler.
enum SettingsSections : Int, RawIntInitable {
case Profile,
Settings,
FAQ,
Feedback,
LogOut
}
That's it, you can now use these functions wherever you might want.
ie:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return SettingsSections.allCases.count
}
This allows us to count the sections without having an additional case devoted to the total number of cases that will need to be added to our switch statements.
Note
After a discussion with another dev about edge cases where an enum
doesn't start at 0, or doesn't increment by 1, I created this more complex version:
protocol RawIntInitable {
static var startingIndex: Int { get }
static var incrementor: Int -> Int { get }
init?(rawValue: Int)
}
extension RawIntInitable {
static var startingIndex: Int {
return 0
}
static var incrementor: Int -> Int {
return { return $0 + 1 }
}
static var allCases: [Self] {
var caseIndex = startingIndex
let generator: AnyGenerator<Self> = anyGenerator {
caseIndex = incrementor(caseIndex)
return Self(rawValue: caseIndex)
}
return Array(generator)
}
}
This way you can define a custom start, and a custom incrementation scheme for your enum if necessary.
Thanks! I think you ought to just make "allCases()" into "cases", though. numberOfCases is redundant when cases.count is so concise. Personally, I use the rule of, "if a function takes no parameters and returns something, it should be a property, not a function".