//
// ViewController.swift
// Calculator_UI&codeBase
//
// Created by t2023-m0023 on 6/20/24.
//
import UIKit
import SnapKit
class ViewController: UIViewController {
let label = UILabel()
let stackview1 = UIStackView()
let stackview2 = UIStackView()
let stackview3 = UIStackView()
let stackview4 = UIStackView()
let clcStackVeiw = UIStackView()
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
}
private func configureUI() {
// 배경 컬러지정
view.backgroundColor = .black
//라벨 설정
label.text = "0"
label.textColor = .white
label.textAlignment = .right
label.font = UIFont.boldSystemFont(ofSize: 60)
// 라벨을 뷰에 추가하고 제약 조건을 설정
view.addSubview(label)
label.snp.makeConstraints {
$0.leading.equalToSuperview().inset(30)
$0.trailing.equalToSuperview().inset(30)
$0.top.equalToSuperview().inset(200)
$0.height.equalTo(100)
}
makeHorizontalStackView()
}
private func makeHorizontalStackView() {
// 스택뷰를 4개를 만들어 줘야함
// 각각의 스택뷰에 버튼타이틀 설정 할 수있는 함수 필요
let stackViews = [stackview1, stackview2, stackview3, stackview4]
let buttonTitle = [["7", "8", "9", "+"], ["4", "5", "6", "-"], ["1", "2", "3", "*"], ["AC", "0", "=", "/"]]
// for 반복문 사용 스택 뷰의 속성을 설정
for (index, stackview) in stackViews.enumerated() {
setHorizontalStackView(stackview: stackview)
makeButtonStackView(stackview: stackview, titles: buttonTitle[index])
}
func setHorizontalStackView(stackview : UIStackView){
stackview.axis = .horizontal
stackview.backgroundColor = .black
stackview.spacing = 10
stackview.distribution = .fillEqually
view.addSubview(stackview)
stackview.snp.makeConstraints{
$0.width.equalTo(350)
$0.height.equalTo(80)
$0.centerX.equalToSuperview()
}
}
func makeButtonStackView (stackview: UIStackView, titles: [String]){
for title in titles {
let button = UIButton()
//버튼 타이틀이 연산자 operator와 숫자를 숫자로 변환
//숫자로 변환이 되면 검정
if let _ = Int(title) {
button.backgroundColor = UIColor(red: 58/255, green: 58/255, blue: 58/255, alpha: 1.0)
button.addTarget(self, action: clickNum(:), for: .touchUpInside)
//숫자로 변환이 안되면 오렌지
} else {
button.backgroundColor = .orange
button.addTarget(self, action: clickOperator(:), for: .touchUpInside)
}
button.setTitle(String(title), for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 30)
button.frame.size.height = 80
button.frame.size.width = 80
button.layer.cornerRadius = 40
stackview.addArrangedSubview(button)
}
}
makeVerticalstackView()
}
private func makeVerticalstackView() {
clcStackVeiw.axis = .vertical
clcStackVeiw.backgroundColor = .black
clcStackVeiw.spacing = 10
clcStackVeiw.distribution = .fillEqually
view.addSubview(clcStackVeiw)
clcStackVeiw.snp.makeConstraints {
$0.width.equalTo(350)
$0.top.equalTo(label.snp.bottom).offset(60)
$0.centerX.equalToSuperview()
}
//가로 스텍뷰를 세로 스택뷰에 추가해주기
clcStackVeiw.addArrangedSubview(stackview1)
clcStackVeiw.addArrangedSubview(stackview2)
clcStackVeiw.addArrangedSubview(stackview3)
clcStackVeiw.addArrangedSubview(stackview4)
}
@objc func clickNum(_ sender: UIButton) {
print()
}
@objc func clickOperator(_ sender: UIButton) {
print()
}
}
1️⃣ Lv. 6 ~ 8
//
// ViewController.swift
// Calculator_UI&codeBase
//
// Created by t2023-m0023 on 6/20/24.
//
import UIKit
import SnapKit
class ViewController: UIViewController {
// 화면에 표시될 레이블과 스택뷰
let label = UILabel()
let stackview1 = UIStackView()
let stackview2 = UIStackView()
let stackview3 = UIStackView()
let stackview4 = UIStackView()
let clcStackVeiw = UIStackView()
// 현재 표시되고 있는 텍스트
var currentText = "0"
override func viewDidLoad() {
super.viewDidLoad()
// 초기 UI 설정 및 스택뷰 생성
configureUI()
makeHorizontalStackView()
makeVerticalstackView()
}
// UI를 설정하는 메서드
private func configureUI() {
view.backgroundColor = .black // 배경 검정색
label.text = currentText // 초기 텍스트 설정
label.textColor = .white // 텍스트 색상 흰색
label.textAlignment = .right // 텍스트 정렬 오른쪽
label.font = UIFont.boldSystemFont(ofSize: 60) // 굵은 폰트 60
// 레이블 추가 , 설정
view.addSubview(label)
label.snp.makeConstraints {
$0.leading.equalToSuperview().inset(30) // 왼쪽 여백 30
$0.trailing.equalToSuperview().inset(30) // 오른쪽 여백 30
$0.top.equalToSuperview().inset(200) // 상단여백 200
$0.height.equalTo(100) // 높이 100
}
}
// 가로스택뷰 생성 버튼추가 메서드
private func makeHorizontalStackView() {
let stackViews = [stackview1, stackview2, stackview3, stackview4]
let buttonTitle = [["7", "8", "9", "+"], ["4", "5", "6", "-"], ["1", "2", "3", "*"], ["AC", "0", "=", "/"]]
for (index, stackview) in stackViews.enumerated() {
setHorizontalStackView(stackview: stackview) // 가로 스택뷰 속성 설정
makeButtonStackView(stackview: stackview, titles: buttonTitle[index]) // 버튼을 생성, 스택뷰에 추가
}
}
// 가로 스택뷰 속성 설정 메서드
private func setHorizontalStackView(stackview: UIStackView) {
stackview.axis = .horizontal // 가로 방향 정렬
stackview.backgroundColor = .black // 배경색 검은색
stackview.spacing = 10 // 요소 간의 간격 10 포인트
stackview.distribution = .fillEqually // 균등하게 배치
// 스택뷰 추가하고 제약조건 설정
view.addSubview(stackview)
stackview.snp.makeConstraints {
$0.width.equalTo(350) // 너비 350
$0.height.equalTo(80) // 높이 80
$0.centerX.equalToSuperview() // 수평 가운데 정렬
}
}
// 버튼생성, 가로스택뷰 추가하는 함수
private func makeButtonStackView(stackview: UIStackView, titles: [String]) {
for title in titles {
let button = UIButton()
// 숫자 버튼인지 연산자 버튼인지 확인한후 스타일과 액션 설정
if let _ = Int(title) {
button.backgroundColor = UIColor(red: 58/255, green: 58/255, blue: 58/255, alpha: 1.0) // 숫자 버튼 배경색
button.addTarget(self, action: #selector(clickNum(_:)), for: .touchUpInside) // 숫자 버튼 액션 설정
} else {
button.backgroundColor = .orange // 연산자 버튼 배경색
button.addTarget(self, action: #selector(clickOperator(_:)), for: .touchUpInside) // 연산자 버튼 클릭 액션을 추가
}
//버튼 텍스트 설정
button.setTitle(String(title), for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 30) // 버튼 텍스트 굵은폰트 크기 30
button.frame.size.height = 80 // 버튼 높이 80 포인트
button.frame.size.width = 80 // 버튼 너비 80 포인트
button.layer.cornerRadius = 40 // 버튼 모서리 둥글게
stackview.addArrangedSubview(button) // 버튼 가로 스택뷰에 추가
}
}
// 세로 스택뷰 생성, 가로 스택뷰 추가
private func makeVerticalstackView() {
clcStackVeiw.axis = .vertical // 세로 방향 정렬
clcStackVeiw.backgroundColor = .black // 배경색 검은색
clcStackVeiw.spacing = 10 // 요소 간격을 10 포인트
clcStackVeiw.distribution = .fillEqually // 균등 배치
// 세로 스택뷰 화면에 추가, 제약조건 설정
view.addSubview(clcStackVeiw)
clcStackVeiw.snp.makeConstraints {
$0.width.equalTo(350) // 너비 350
$0.top.equalTo(label.snp.bottom).offset(60) // 레이블 아래 여백 60
$0.centerX.equalToSuperview() // 수평 가운데 정렬
}
// 가로 스택뷰들을 세로 스택뷰에 추가
clcStackVeiw.addArrangedSubview(stackview1)
clcStackVeiw.addArrangedSubview(stackview2)
clcStackVeiw.addArrangedSubview(stackview3)
clcStackVeiw.addArrangedSubview(stackview4)
}
// 숫자 버튼 클릭 시 호출되는 메서드
@objc func clickNum(_ sender: UIButton) {
guard let clickedButtonText = sender.currentTitle else { return }
// 현재 텍스트가 "0"일 때 클릭된 버튼이 0이 아닌경우, 0제거 클릭된 버튼 텍스트로 대체
if currentText == "0" && clickedButtonText != "0" {
currentText = clickedButtonText
} else {
currentText += clickedButtonText
}
updateLabel() // 레이블 업데이트
}
// 연산자 버튼 클릭 시 호출되는 메서드
@objc func clickOperator(_ sender: UIButton) {
guard let clickedButtonText = sender.currentTitle else { return }
// 클릭된 연산자에 따라 동작 수행
switch clickedButtonText {
case "AC":
currentText = "0" // AC 버튼 클릭 시 초기화
case "=":
if let result = calculate(expression: currentText) {
currentText = String(result) // = 버튼 클릭 시 계산, 결과를 텍스트로 설정
} else {
currentText = "ERROR" // 잘못된 수식, 에러 표시
}
default:
currentText += clickedButtonText // 기타 연산자, 텍스트에 추가
}
updateLabel() // 레이블을 업데이트
}
// 수식을 계산, 결과를 반환하는 메서드
func calculate(expression: String) -> Int? {
// 입력한 수식이 비어있는 경우
guard !expression.isEmpty else {
print("수식이 비어있습니다.")
return nil
}
// 연산자를 포함한 수식, 정규 표현식 사용하여 검사
let regex = try! NSRegularExpression(pattern: "^[0-9]+([\\+\\-\\*\\/][0-9]+)*$")
let range = NSRange(location: 0, length: expression.utf16.count)
// 정규 표현식에 맞지 않는 경우
guard regex.firstMatch(in: expression, options: [], range: range) != nil else {
print("잘못된 수식입니다.")
return nil
}
// NSExpression을 사용해 계산
let nsExpression = NSExpression(format: expression)
// 계산 결과를 반환
if let result = nsExpression.expressionValue(with: nil, context: nil) as? Int {
return result
} else {
print("잘못된 수식입니다.") // 잘못된 수식일 경우, 메시지를 출력
return nil
}
}
// 레이블의 텍스트를 업데이트
func updateLabel() {
label.text = currentText // 레이블 현재 텍스트를 설정
}
}
🩷 를 클릭하면 Foundation 프레임워크 클래스를 볼 수 있습니다
expressionValue(with: , context:)
let expression = NSExpression(format: "2 + 3") if let result = expression.expressionValue(with: nil, context: nil) as? NSNumber { print("Result:", result.intValue) // 출력: Result: 5 }
let variableName = "x" let variableValue = 10 let expression = NSExpression(format: "\(variableName) * 2") let context = ["x": variableValue] if let result = expression.expressionValue(with: nil, context: context) as? NSNumber { print("Result:", result.intValue) // 출력: Result: 20 }
let expression = NSExpression(format: "sqrt(25)") if let result = expression.expressionValue(with: nil, context: nil) as? NSNumber { print("Result:", result.doubleValue) // 출력: Result: 5.0 }
👉 필요하다고 생각한 이유 :
👉 수정