Swift 계산기 만들기 (UIKit-Coadbase)
2024. 6. 28. 16:50
반응형
import UIKit
class ViewController: UIViewController {
var display = UILabel() // 결과를 표시할 라벨
var verticalStackView = UIStackView() // 버튼을 배치할 수직 스택뷰
// 버튼에 표시할 숫자 및 연산자 배열
let buttons = [["7", "8", "9", "+"], ["4", "5", "6", "-"], ["1", "2", "3", "x"], ["AC", "0", "=", "÷"]]
// 뷰가 로드될 때 호출되는 메서드
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
setupTextLabel() // 텍스트 라벨 설정
setupVerticalStackView() // 수직 스택뷰 설정
}
// 텍스트 라벨을 설정하는 메서드
private func setupTextLabel() {
display.text = "0" // 초기 텍스트 설정
display.textColor = .white // 텍스트 색상 설정
display.font = UIFont.boldSystemFont(ofSize: 60) // 텍스트 폰트 설정
display.textAlignment = .right // 텍스트 정렬 설정
view.addSubview(display) // 라벨을 뷰에 추가
// 오토레이아웃 제약조건 설정
display.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
display.heightAnchor.constraint(equalToConstant: 100),
display.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
display.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30),
display.topAnchor.constraint(equalTo: view.topAnchor, constant: 200)
])
}
// 수직 스택뷰를 설정하는 메서드
private func setupVerticalStackView() {
verticalStackView.axis = .vertical // 수직 방향 설정
verticalStackView.backgroundColor = .black // 배경 색상 설정
verticalStackView.spacing = 10 // 스택뷰 사이의 간격 설정
verticalStackView.distribution = .fillEqually // 스택뷰 요소 간 균등 배치
view.addSubview(verticalStackView) // 수직 스택뷰를 뷰에 추가
// 오토레이아웃 제약조건 설정
verticalStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
verticalStackView.widthAnchor.constraint(equalToConstant: 350),
verticalStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
verticalStackView.topAnchor.constraint(equalTo: display.bottomAnchor, constant: 60)
])
// 버튼 배열을 이용해 수평 스택뷰 생성 및 추가
for row in buttons {
let horizontalStackView = createHorizontalStackView(row)
verticalStackView.addArrangedSubview(horizontalStackView)
// 오토레이아웃 제약조건 설정
horizontalStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
horizontalStackView.heightAnchor.constraint(equalToConstant: 80),
horizontalStackView.widthAnchor.constraint(equalToConstant: 350),
horizontalStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
}
}
// 수평 스택뷰를 생성하는 메서드
private func createHorizontalStackView(_ buttons: [String]) -> UIStackView {
let stackView = UIStackView() // 수평 스택뷰 생성
stackView.axis = .horizontal // 수평 방향 설정
stackView.backgroundColor = .black // 배경 색상 설정
stackView.spacing = 10 // 스택뷰 요소 간 간격 설정
stackView.distribution = .fillEqually // 스택뷰 요소 간 균등 배치
for buttonText in buttons {
let button = createButton(buttonText) // 버튼 생성
stackView.addArrangedSubview(button) // 버튼을 수평 스택뷰에 추가
}
return stackView
}
// 버튼을 생성하는 메서드
private func createButton(_ text: String) -> UIButton {
let button = UIButton() // 버튼 생성
button.setTitle(text, for: .normal) // 버튼 타이틀 설정
button.titleLabel?.font = .boldSystemFont(ofSize: 30) // 버튼 폰트 설정
if Int(text) != nil {
button.backgroundColor = UIColor(red: 58/255, green: 58/255, blue: 58/255, alpha: 1.0) // 숫자 버튼 배경색 설정
button.addTarget(self, action: #selector(didTapNumberButton(_:)), for: .touchUpInside) // 숫자 버튼 액션 설정
} else {
button.backgroundColor = .orange // 연산자 버튼 배경색 설정
button.addTarget(self, action: #selector(didTapOperateButton(_:)), for: .touchUpInside) // 연산자 버튼 액션 설정
}
button.layer.cornerRadius = 40 // 버튼 모서리 둥글게 설정
return button
}
// 숫자 버튼이 눌렸을 때 호출되는 메서드
@objc func didTapNumberButton(_ sender: UIButton) {
if let currentText = display.text, let newText = sender.titleLabel?.text {
// 현재 텍스트가 "0"이면 새로운 숫자로 대체
if currentText == "0" {
display.text = newText
} else {
// 그렇지 않으면 기존 텍스트에 새로운 숫자를 추가
display.text = removeLeadingZero(currentText + newText)
}
}
}
// 연산자 버튼이 눌렸을 때 호출되는 메서드
@objc func didTapOperateButton(_ sender: UIButton) {
if let buttonText = sender.titleLabel?.text {
switch buttonText {
case "AC":
// "AC" 버튼을 눌렀을 때 텍스트를 "0"으로 설정
display.text = "0"
case "=":
// "=" 버튼을 눌렀을 때 계산 수행
if let expression = display.text, let result = calculate(expression: expression) {
display.text = String(result)
}
default:
// 기타 연산자 버튼을 눌렀을 때 텍스트에 연산자 추가
if let currentText = display.text {
display.text = currentText + buttonText
}
}
}
}
// 입력된 숫자에서 선행 0을 제거하는 메서드
private func removeLeadingZero(_ input: String) -> String {
var result = input
if result.hasPrefix("0") && result.count > 1 {
result.removeFirst()
}
return result
}
// 주어진 식(expression)을 계산하는 메서드
private func calculate(expression: String) -> Int? {
// 곱셈과 나눗셈 기호를 NSExpression이 인식할 수 있는 형식으로 변환
let expressionWithOperators = expression.replacingOccurrences(of: "x", with: "*").replacingOccurrences(of: "÷", with: "/")
// NSExpression을 사용하여 식을 계산
let exp = NSExpression(format: expressionWithOperators)
if let result = exp.expressionValue(with: nil, context: nil) as? Double {
// 결과를 정수로 반환
return Int(result)
}
return nil
}
}
반응형