SwiftUI로 계산기 만들기
Button 사이즈를 잡아주는 함수를 만든다.
buttonWidth 같은 경우에는 0 버튼일 경우에는 다른 버튼들과는 다르게 넓은 width를 줘야하기 때문에 따로 조건을 넣어준다.
/// Button Width
func buttonWidth(item: CalculatorButton) -> CGFloat {
// 0일 경우에만 넓은 width를 준다!
if item == .zero {
return ((UIScreen.main.bounds.width - (4 * 12)) / 4) * 2
}
return (UIScreen.main.bounds.width - (5 * 12)) / 4
}
/// Button Height
func buttonHeight() -> CGFloat {
return (UIScreen.main.bounds.width - (5 * 12)) / 4
}
Button을 enum 형태로 숫자, 연산자로 나눈다.
숫자나 연산자마다 색상도 다르게 적용한다.
enum CalculatorButton: String {
// 숫자
case one = "1"
case two = "2"
case three = "3"
case four = "4"
case five = "5"
case six = "6"
case seven = "7"
case eight = "8"
case nine = "9"
case zero = "0"
// 연산자
case subtract = "\u{2212}"
case add = "\u{002B}"
case divide = "\u{00F7}"
case multiply = "\u{00D7}"
case equal = "="
case clear = "AC"
case decimal = "."
case percent = "%"
case negative = "\u{002B}/-"
var buttonColor: Color {
switch self {
case .add, .subtract, .divide, .multiply, .equal:
return Color(red: 244 / 255, green: 196 / 255, blue: 230 / 255)
case .clear, .negative, .percent:
return Color(red: 196 / 255, green: 244 / 255, blue: 239 / 255)
default:
return Color(red: 215 / 255, green: 196 / 255, blue: 244 / 255)
}
}
var foregroundColor: Color {
switch self {
case .clear, .negative, .percent:
return Color(.black)
default:
return Color(.white)
}
}
}
enum Operation {
case add, subtract, divide, multiply, none
}
전체 계산기 화면의 버튼들의 UI를 잡아주는 코드이다.
@State 변수를 사용하여 현재 화면에 보여지는 값(displayNumber), 실행숫자(runningNumber), 연산자(currentOperator), 그리고 화면 초기화 여부(shouldClearDisplay)를 관리한다.
struct MainView: View {
@State private var displayNumber = "0"
@State private var runningNumber = 0
@State private var currentOperator: Operation = .none
@State private var shouldClearDisplay = false
private let buttons: [[CalculatorButton]] = [
[.clear, .negative, .percent, .divide],
[.seven, .eight, .nine, .multiply],
[.four, .five, .six, .subtract],
[.one, .two, .three, .add],
[.zero, .decimal, .equal]
]
var body: some View {
VStack {
Spacer()
HStack {
Spacer()
Text("\(displayNumber)")
.bold()
.font(.system(size: 80))
.foregroundColor(.white)
}
.padding()
ForEach(buttons, id: \.self) { button in
HStack(spacing: 10) {
ForEach(button, id: \.self) { item in
Button {
calculate(button: item)
} label: {
Text(item.rawValue)
.font(.system(size: 40) .bold())
.frame(width: buttonWidth(item: item), height: buttonHeight())
.background(item.buttonColor)
.clipShape(.rect(cornerRadius: buttonWidth(item: item) / 2))
.foregroundColor(item.foregroundColor)
}
}
}
}
.padding(.bottom, 7)
}
.padding()
.background(Color.black)
.edgesIgnoringSafeArea(.all)
}
}
계산을 하는 calculate 함수이다.
extension MainView {
func calculate(button: CalculatorButton) {
switch button {
case .add, .subtract, .multiply, .divide, .equal:
if button == .add {
currentOperator = .add
runningNumber = Int(displayNumber) ?? 0
}
else if button == .subtract {
currentOperator = .subtract
runningNumber = Int(displayNumber) ?? 0
}
else if button == .multiply {
currentOperator = .multiply
runningNumber = Int(displayNumber) ?? 0
}
else if button == .divide {
currentOperator = .divide
runningNumber = Int(displayNumber) ?? 0
}
else if button == .equal {
let runningValue = runningNumber
let currentValue = Int(displayNumber) ?? 0
switch self.currentOperator {
case .add: displayNumber = "\(runningValue + currentValue)"
case .subtract: displayNumber = "\(runningValue - currentValue)"
case .multiply: displayNumber = "\(runningValue * currentValue)"
case .divide: displayNumber = "\(runningValue / currentValue)"
case .none:
break
}
}
shouldClearDisplay = true
case .clear:
displayNumber = "0"
runningNumber = 0
currentOperator = .none
shouldClearDisplay = false
case .decimal, .negative, .percent:
break
default: // 숫자일 경우
if shouldClearDisplay {
displayNumber = button.rawValue
shouldClearDisplay = false
} else {
let number = button.rawValue
if displayNumber == "0" {
displayNumber = number
}
else {
displayNumber = "\(displayNumber)\(number)"
}
}
}
}
}
728x90
'📱 Mobile > iOS' 카테고리의 다른 글
[iOS - HealthKit] HealthKit 데이터에 대해서 (0) | 2024.06.13 |
---|---|
[iOS - UIKit] TextField 입력에 따라 Button 활성화 유무 (1) | 2024.06.04 |
[iOS - UIKit] Keyboard 내려가게 하는 방법 (return 키, 여백 눌렀을 때, 드래그 등) (0) | 2024.05.22 |
[iOS - UIKit] UITextField에 Padding 값 적용하는 방법 (좌우 여백 주기) (0) | 2024.05.17 |
[iOS - Network] iOS에서 서버 통신 하는 방법 (URL Session, Alamofire, Moya) (0) | 2024.05.16 |