📱 모바일 프로그래밍/iOS 프로그래밍 기초
iOS 프로그래밍 12주차
SA성아
2024. 11. 20. 16:48
오토 레이아웃을 잡아주지 않아서 Issue navigator가 뜸
오토 레이아웃(Auto Layout) : iOS 앱 개발에서 UI 요소(뷰)의 크기와 위치를 다양한 화면 크기와 방향에 따라 유동적으로 조정할 수 있도록 돕는 레이아웃 시스템
3개의 아울렛 연결
입력을 받아들이는 2개의 아울렛과 결과를 나타내는 아울렛 1개 연결
Oulet 3개, Action 1개의 간단한 앱
cmd + R 후 계산을 누르면 콘솔창에 정상이 뜸
text필트에 값을 넣지 않으면 크래시가 나는 소스
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtWeight: UITextField!
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var lblResult: UILabel!
@IBAction func calcBmi(_ sender: UIButton) {
let weight = Double(txtWeight.text!)!
let height = Double(txtHeight.text!)!
let bmi = weight / (height*height*0.0001) // kg/m*m
let shortenedBmi = String(format: "%.1f", bmi)
var body = ""
if bmi >= 40 {
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
body = "정상"
} else {
body = "저체중"
}
print("BMI:\(shortenedBmi), 판정:\(body)")
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
1. txtHeight.text와 txtWeight.text
- UITextField의 text 속성은 옵셔널(Optional) 타입인 String?입니다.
즉, 값이 있을 수도 있고 없을 수도 있는 상태를 나타냅니다.
강제로 옵셔널을 해제하기 위해 !를 사용한 것입니다.
txtHeight.text! // 옵셔널(String?) → String으로 강제 변환
2. Double(txtHeight.text!)
- Double() 생성자는 문자열을 받아 Double로 변환하는데, 이 역시 반환값이 **옵셔널(Optional)**입니다.
변환이 실패할 경우 nil을 반환하기 때문에, 이를 다시 강제 언래핑한 것입니다.
Double(txtHeight.text!)! // Double? → Double로 강제 변환
값을 넣지 않으면 경고문을 띄우게 함
소스정렬
cmd + A -> ctrl + I
//
// ViewController.swift
// BMI_psa
//
// Created by redmist on 11/13/24.
//
import UIKit
class ViewController: UIViewController {
// MARK: - 아웃렛 연결
@IBOutlet weak var txtWeight: UITextField! // 체중 입력 필드
@IBOutlet weak var txtHeight: UITextField! // 키 입력 필드
@IBOutlet weak var lblResult: UILabel! // 결과를 표시할 레이블
// MARK: - BMI 계산 버튼 액션
@IBAction func calcBmi(_ sender: UIButton) {
// 1. 입력값이 비어 있는지 확인
if txtHeight.text == "" || txtWeight.text == "" {
lblResult.textColor = .red // 경고 메시지는 빨간색으로 표시
lblResult.text = "키와 체중을 입력하세요."
return // 입력값이 없으면 함수 종료
} else {
// 2. 입력값을 Double로 변환 (강제 언래핑 사용)
let weight = Double(txtWeight.text!)! // 체중 값
let height = Double(txtHeight.text!)! // 키 값
// 3. BMI 계산 (단위: kg/m²)
let bmi = weight / (height * height * 0.0001)
let shortenedBmi = String(format: "%.1f", bmi) // 소수점 한 자리로 포맷
// 4. BMI 값에 따라 판정 및 색상 결정
var body = "" // BMI 상태를 저장할 변수
var color = UIColor.white // 결과 레이블의 배경색 기본값
if bmi >= 40 {
color = UIColor(displayP3Red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) // 빨간색
body = "3단계 비만"
} else if bmi >= 30 && bmi < 40 {
color = UIColor(displayP3Red: 0.7, green: 0.0, blue: 0.0, alpha: 1.0) // 짙은 빨간색
body = "2단계 비만"
} else if bmi >= 25 && bmi < 30 {
color = UIColor(displayP3Red: 0.4, green: 0.0, blue: 0.0, alpha: 1.0) // 어두운 빨간색
body = "1단계 비만"
} else if bmi >= 18.5 && bmi < 25 {
color = UIColor(displayP3Red: 0.0, green: 0.2, blue: 0.7, alpha: 1.0) // 파란색
body = "정상"
} else {
color = UIColor(displayP3Red: 0.0, green: 0.9, blue: 0.0, alpha: 1.0) // 초록색
body = "저체중"
}
// 5. 결과 레이블 업데이트
lblResult.backgroundColor = color // 판정에 따라 배경색 설정
lblResult.clipsToBounds = true // 코너를 둥글게 하기 위해 필요한 설정
lblResult.layer.cornerRadius = 7 // 모서리를 둥글게 설정
lblResult.text = "BMI:\(shortenedBmi), 판정:\(body)" // 결과 텍스트 설정
}
}
// MARK: - 뷰 초기화
override func viewDidLoad() {
super.viewDidLoad()
// 추가적인 초기 설정 코드가 필요한 경우 작성
}
}
Tab Bar Controller
구분 | Manual Segue | Relationship Segue |
용도 | 특정 이벤트(버튼 클릭 등) 발생 시 화면 전환. | 컨테이너 뷰 컨트롤러(예: UITabBarController, UISplitViewController)에서 하위 뷰 컨트롤러 간 관계를 설정. |
트리거 방식 | 코드 또는 인터페이스 빌더에서 직접 호출. | 인터페이스 빌더에서 뷰 컨트롤러 간 관계를 설정하며 자동으로 호출. |
실행 시점 | 이벤트(버튼 클릭, 제스처 등)가 발생할 때 코드로 트리거. | 앱 실행 시, 관계가 정의된 컨트롤러들이 자동으로 연결됨. |
연결 방법 | 스토리보드에서 control + drag로 두 컨트롤러 연결 후 세그웨이 선택. | 컨테이너 컨트롤러와 하위 뷰 컨트롤러를 연결 (스토리보드에서 직접 설정). |
구현 방식 | performSegue(withIdentifier:sender:) 메서드를 통해 호출 가능. | 별도의 호출 코드 없이 컨테이너 뷰 컨트롤러가 자동 관리. |
Identifier 필요 여부 | 필요함 (Segue Identifier로 구분). | 필요 없음. |
사용 예 | 버튼 클릭 시 상세 화면으로 이동. | UITabBarController의 탭 구성, UISplitViewController의 마스터-디테일 연결. |
적합한 시나리오 | 특정 사용자 액션 기반 화면 전환. | 컨테이너 컨트롤러 내 하위 컨트롤러 관계 설정. |
출처: iOS 프로그래밍 기초 강의 자료