계산기 앱 만들어보기
import SwiftUI
enum ButtonType: String {
case first = "1", second = "2", third = "3", forth = "4", fifth = "5"
case sixth = "6", seventh = "7", eighth = "8", nineth = "9", zero = "0"
case dot = ".", equal = "=", plus = "+", minus = "-", multiple = "*", devide = "/"
case percent = "%", opposite = "+/-", clear = "C"
var backgroundColor: Color {
switch self {
case .first, .second, .third, .forth, .fifth, .sixth, .seventh, .eighth, .nineth, .zero, .dot:
return Color("NumberButton")
case .plus, .minus, .multiple, .devide, .equal:
return Color.orange
case .clear, .opposite, .percent:
return Color.gray
}
}
var forgroundColor: Color {
switch self {
case .first, .second, .third, .forth, .fifth, .sixth, .seventh, .eighth, .nineth, .zero, .dot:
return Color.white
case .plus, .minus, .multiple, .devide, .equal:
return Color.white
case .clear, .opposite, .percent:
return Color.black
}
}
}
struct ContentView: View {
@State private var totalNumber: String = "0"
@State private var currentExpression: String = ""
@State private var didCalculate: Bool = false
private let buttonData: [[ButtonType]] = [
[ .clear , .opposite , .percent , .devide ],
[ .seventh , .eighth , .nineth , .multiple ],
[ .forth , .fifth , .sixth , .minus ],
[ .first , .second , .third , .plus ],
[ .zero , .dot , .equal ]
]
var body: some View {
ZStack {
Color.black.ignoresSafeArea(.all)
VStack {
Spacer()
HStack {
Spacer()
Text(currentExpression)
.padding()
.font(.system(size: 24))
.foregroundColor(.white)
.lineLimit(1)
.minimumScaleFactor(0.5)
.frame(maxWidth: .infinity, alignment: .trailing)
}
HStack {
Spacer()
Text(totalNumber)
.padding()
.font(.system(size: 73))
.foregroundColor(.white)
.lineLimit(1)
.minimumScaleFactor(0.5)
}
ForEach(buttonData, id: \.self) { line in
HStack {
ForEach(line, id: \.self) { row in
Button {
handleInput(row)
} label: {
Text(row.rawValue)
.frame(width: row == .zero ? 160 : 80, height: 80)
.background(row.backgroundColor)
.cornerRadius(40)
.foregroundColor(row.forgroundColor)
.font(.system(size: 33))
}
}
}
}
}
}
.padding()
}
func handleInput(_ button: ButtonType) {
switch button {
case .clear:
totalNumber = "0"
currentExpression = ""
didCalculate = false
case .plus, .minus, .multiple, .devide:
if didCalculate {
currentExpression = totalNumber
didCalculate = false
}
currentExpression += button.rawValue
totalNumber = button.rawValue
case .equal:
totalNumber = calculateExpression(currentExpression)
didCalculate = true
currentExpression = totalNumber
case .percent:
if let number = Double(totalNumber) {
totalNumber = formatResult(number / 100)
currentExpression = totalNumber
}
case .opposite:
if let number = Double(totalNumber) {
totalNumber = formatResult(number * -1)
currentExpression = totalNumber
}
default:
if didCalculate {
totalNumber = button.rawValue
currentExpression = button.rawValue
didCalculate = false
} else {
if totalNumber == "0" || totalNumber == "+" || totalNumber == "-" || totalNumber == "*" || totalNumber == "/" {
totalNumber = button.rawValue
} else {
totalNumber += button.rawValue
}
currentExpression += button.rawValue
}
}
}
func calculateExpression(_ expression: String) -> String {
let expressionWithSpaces = expression.replacingOccurrences(of: "+", with: " + ")
.replacingOccurrences(of: "-", with: " - ")
.replacingOccurrences(of: "*", with: " * ")
.replacingOccurrences(of: "/", with: " / ")
let components = expressionWithSpaces.split(separator: " ")
var values: [Double] = []
var operations: [String] = []
for component in components {
if let value = Double(component) {
values.append(value)
} else {
operations.append(String(component))
}
}
var result: Double = values[0]
for i in 0..<operations.count {
let operation = operations[i]
let nextValue = values[i + 1]
switch operation {
case "*":
result *= nextValue
case "/":
result /= nextValue
case "+":
result += nextValue
case "-":
result -= nextValue
default:
break
}
}
return formatResult(result)
}
func formatResult(_ result: Double) -> String {
if result.truncatingRemainder(dividingBy: 1) == 0 {
return String(Int(result))
} else {
return String(result)
}
}
}
#Preview {
ContentView()
}
추가사항
- /, +, -등 계산기호 기능 추가
- 상단에 수식 전체 미리보기 추가
- 복합연산 가능
수정사항
- 아이폰 전체 백그라운드 컬러 지정 아직도 방법 못찾음