Reputation: 3102
I'm still fairly new to SwiftUI & Swift (from Javascript background) and I am working on creating a clone calculator app.
My CalculatorView currently has a button layout which is passed in to CalculatorActions and does what it needs to do to update the CalculatorView display.
// CalculatorView.swift
// buttons = View layout with enum defined buttons
let buttons: [[Calculator]] = [
[.ac, .plusMinus, .percent, .divide],
[.seven, .eight, .nine, .multiply],
[.four, .five, .six, .minus],
[.one, .two, .three, .plus],
[.zero, .period, .equal]
]
// var body
// ...
ForEach(buttons, id: \.self) { row in
HStack(spacing: sizing.spacing) {
ForEach(row, id: \.self) { button in
Button(action: {
actions.updateDisplay(button: button)
}, label: {
ButtonView(button: button, sizing: sizing)
})
}
}
}
// ...
I have an enum I am using for my Calculator model like so:
// Calculator.swift (Enum Calculator Model)
enum Calculator: String {
case ac, clear, plusMinus, percent, divide
case seven, eight, nine, multiply
case four, five, six, minus
case one, two, three, plus
case zero, period, equal
var label: String {
switch (self) {
case .zero: return "0"
case .one: return "1"
case .two: return "2"
case .three: return "3"
// ...
I access these enums through the class in a separate file that I have with a controller where I often do comparisons or to access the label of whatever button was passed in like so:
// CalculatorActions.swift (Calculator Controller)
class CalculatorActions: ObservableObject {
// ...
func updateDisplay(button: Calculator) -> Void {
// Clear
if button == Calculator.ac {
self.resetEverything()
self.lastButtonPressed = button
return
}
if button == Calculator.plusMinus {
// ...
self.append(Calculator.one.label)
I would love to clean up this and have the CalculatorActions controller class, which is in a separate file, essentially do enum comparisons like this
// CalculatorActions.swift (Calculator Controller)
class CalculatorActions: ObservableObject {
// ...
func updateDisplay(button: Calculator) -> Void {
// Clear
if button == .ac {
self.resetEverything()
self.lastButtonPressed = button
return
}
if button == .plusMinus {
// ...
self.append(.one.label)
but for obvious reasons, you can't extend a class with an enum.
Essentially, within CalculatorActions.swift, I want to be able to use enum from Calculator.swift .plusMinus
instead of Calculator.plusMinus
.
If possible or not, please school me.
Upvotes: 0
Views: 689
Reputation: 54486
Swift can automatically infer types
In your function:
func updateDisplay(button: Calculator) { // no need to specify `Void` explicitly
// Clear
if button == .ac { // you can skip `Calculator` and use `.ac`, Swift knows that button is of type `Calculator`
resetEverything()
lastButtonPressed = button // no need to use self (individual preference)
// you don't need to return from `Void` function
}
if button == .plusMinus { // again, you can replace `Calculator.plusMinus` with `.plusMinus`
// ...
self.append(.one.label) // `append` accepts a `string` parameter, you may need to make it accept `Calculator` parameter instead and call it like `append(.one)`
}
Basically you can use .plusMinus
instead of Calculator.plusMinus
wherever Swift is able to infer the type automatically. Which can be when comparing .plusMinus
with another Calculator
variable, passing the Calculator
parameter...
Just remember Swift needs to know you're passing the Calculator
variable.
Note that you can specify a rawValue
directly:
enum Calculator: String {
case one = "1", two = "2", three = "3", plus = "+"
...
var label: String {
rawValue
}
}
I'd recommend also renaming Calculator
to something more descriptive. It's not a calculator, but a part of it (CalculatorItem
, CalculatorButton
...).
Upvotes: 1
Reputation: 805
Maybe it's an answer (as far I can understand question):
enum Calculator: String {
case ac, clear, plusMinus, percent, divide
case seven, eight, nine, multiply
case four, five, six, minus
case one, two, three, plus
case zero, period, equal
var label: String {
return self.rawValue
}
}
If you want assign some var to enum element, this var must have defined type:
var calc: Calculator
calc = .eight
and if your append
function is defined as
func append(_ calc: Calculator) {...}
you can call it:
append(.eight)
Upvotes: 1