BMI 앱 만들기






import UIKit
class ViewController: UIViewController {
// MARK: - IBOutlets
@IBOutlet weak var heightTextField: UITextField!
@IBOutlet weak var weightTextField: UITextField!
@IBOutlet weak var resultLabel: UILabel!
@IBOutlet weak var adviceLabel: UILabel!
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
func setupUI() {
resultLabel.text = ""
adviceLabel.text = ""
}
// MARK: - IBActions
@IBAction func calculateButtonTapped(_ sender: UIButton) {
guard let heightText = heightTextField.text,
let weightText = weightTextField.text,
let height = Double(heightText),
let weight = Double(weightText) else {
resultLabel.text = "숫자를 입력해주세요."
return
}
// cm 단위를 m 단위로 변환
let heightInMeter = height / 100
let bmi = weight / (heightInMeter * heightInMeter)
resultLabel.text = String(format: "BMI: %.1f", bmi)
adviceLabel.text = getBMICategory(bmi)
}
// MARK: - Helper
func getBMICategory(_ bmi: Double) -> String {
switch bmi {
case ..<18.5:
view.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.2)
return "저체중입니다."
case 18.5..<23:
view.backgroundColor = UIColor.systemGreen.withAlphaComponent(0.2)
return "정상 체중입니다."
case 23..<25:
view.backgroundColor = UIColor.systemOrange.withAlphaComponent(0.2)
return "과체중입니다."
default:
view.backgroundColor = UIColor.systemRed.withAlphaComponent(0.2)
return "비만입니다."
}
}
}


스토리보드와 Swift UI의 장단점 비교(표)
| 개념 | 시각적으로 UI를 구성하는 전통 방식 (Interface Builder 이용) | 코드 기반 선언형 UI 프레임워크 |
| 등장 시기 | iOS 3 (2009) 이후 오랫동안 표준 | iOS 13 (2019) 이후 등장, 현재 주류로 전환 중 |
| UI 구성 방식 | 드래그 & 드롭으로 View 배치, AutoLayout 제약조건 수동 설정 | 코드로 UI 선언(Text, VStack, Button 등) → 미리보기(Preview)로 즉시 확인 |
| 초보자 접근성 | 처음엔 시각적으로 직관적, 컴포넌트 이해가 쉬움 | 코드 작성 중심이라 문법에 익숙해져야 함 |
| 레이아웃 관리 | AutoLayout 제약조건을 직접 설정해야 함 → 복잡할 수 있음 | Stack과 Modifier로 유연하고 간결하게 작성 가능 |
| 상호작용 연결 | IBAction, IBOutlet으로 스토리보드 ↔ 코드 연결 필요 | View와 State 바인딩(@State, @Binding)으로 자동 반영 |
| 화면 이동(Navigation) | Segue나 코드 기반 Push / Present 방식 | NavigationStack / NavigationLink로 간단하게 선언 |
| 리팩토링/협업 | 스토리보드 충돌 잦음(특히 Git 병합 시) | 코드 기반이라 버전 관리 용이 |
| 미리보기/반응성 | 실행 후 확인해야 함 | Xcode Preview로 실시간 확인 가능 |
| 기능 확장성 | UIKit 라이브러리 많고 문서 풍부 | SwiftUI는 새로워서 일부 세부 제어는 UIKit보다 제한적 |
| 성능 | 안정적이며 검증된 성능 | 기본 성능은 우수하지만, 커스텀 컨트롤 일부는 UIKit 병행 필요 |
| 학습 곡선 | 초기 진입 쉬움 → AutoLayout, Delegate 패턴이 어려움 | 초반 문법이 생소하지만 익숙해지면 빠른 개발 가능 |
| 권장 시점 | 단순 UI, 학습 목적, 기존 UIKit 코드 유지보수 | 신규 프로젝트, 빠른 프로토타입, 애플 최신 기술 적용 |
| 애플의 방향성 | 유지보수는 계속되지만 점차 비중 축소 | 공식 문서·샘플이 SwiftUI 중심으로 이동 중 |

String에 대해서 알아보자






정상적으로 연결되었는지 확인하기

앱에 아직 남은 문제가 있다.
그것은 바로 옵셔널

아무 값도 넣지 않고 계산 버튼을 누르면 크래시가 발생한다.

코드 변경하기(옵셔널 바인딩):
@IBAction func calcBmi(_ sender: UIButton) {
// 1️⃣ 입력값 검증
guard let heightText = txtHeight.text,
let weightText = txtWeight.text,
!heightText.isEmpty, !weightText.isEmpty else {
updateResultLabel(with: "키와 체중을 입력하세요!", color: .red)
return
}
// 2️⃣ Double 변환
guard let height = Double(heightText),
let weight = Double(weightText) else {
updateResultLabel(with: "숫자만 입력 가능합니다!", color: .red)
return
}
// 3️⃣ BMI 계산
let bmi = weight / (height * height * 0.0001)
let shortenedBmi = String(format: "%.1f", bmi)
let bmiCategory = bmiCategory(for: bmi)
// 4️⃣ 결과 표시
let resultText = "BMI: \(shortenedBmi), 판정: \(bmiCategory)"
updateResultLabel(with: resultText, color: .label)
print(resultText)
}
// MARK: - Helper Functions
private func bmiCategory(for bmi: Double) -> String {
switch bmi {
case ..<18.5: return "저체중"
case 18.5..<25: return "정상"
case 25..<30: return "1단계 비만"
case 30..<40: return "2단계 비만"
default: return "3단계 비만"
}
}
private func updateResultLabel(with text: String, color: UIColor) {
lblResult.text = text
lblResult.textColor = color
}




'공부 > iOS' 카테고리의 다른 글
| iOS 프로그래밍 13주차 (0) | 2025.11.25 |
|---|---|
| iOS 프로그래밍 12주차 (0) | 2025.11.19 |
| iOS 프로그래밍 10주차 (0) | 2025.11.04 |
| iOS 프로그래밍 9주차 (0) | 2025.10.28 |
| iOS 프로그래밍 7주차 (0) | 2025.10.14 |