iOS 오토 레이아웃(Auto Layout)이란?
**iOS 오토 레이아웃(Auto Layout)**은 제약 기반 레이아웃 시스템으로, 화면 크기와 방향이 변하더라도 UI 요소 간의 위치와 크기를 유지하거나 자동으로 조정할 수 있도록 규칙(Constraints)을 설정하는 방식입니다. 이는 다양한 기기와 해상도를 지원하기 위해 만들어졌으며, 다음과 같은 이론적 특징을 가집니다.
1. 제약 조건(Constraints)
오토 레이아웃은 UI 요소 간의 상대적인 위치, 크기, 여백 등 관계를 정의하는 규칙을 기반으로 작동합니다. 제약 조건은 다음과 같은 항목으로 구성됩니다:
- 위치: 한 요소가 다른 요소나 화면의 특정 위치와의 관계.
- 크기: 요소의 너비와 높이.
- 비율: 요소의 크기가 다른 요소나 자체 크기와의 비율.
- 여백: 요소 간의 거리.
예:
- "이 버튼은 화면의 왼쪽 가장자리에서 20pt 떨어져 있어야 한다."
- "이 텍스트 필드의 높이는 버튼의 2배이다."
2. 내재적 콘텐츠 크기(Intrinsic Content Size)
각 UI 요소는 고유의 기본 크기를 가집니다. 이 크기는 요소의 콘텐츠에 의해 결정됩니다.
- 예: 라벨의 크기는 텍스트 길이에 따라 달라질 수 있습니다.
- 오토 레이아웃은 이 기본 크기를 참고해 적절한 제약 조건을 설정합니다.
3. 우선순위(Priority)
모든 제약 조건에는 우선순위 값이 부여됩니다(기본값: 1000).
우선순위는 충돌하는 제약 조건 중 어떤 것을 우선적으로 적용할지를 결정합니다. 낮은 우선순위를 가진 제약 조건은 필요할 경우 무시될 수 있습니다.
예:
- "라벨의 크기는 텍스트에 맞게 조정되지만, 최대 너비는 300pt를 넘을 수 없다."
- 텍스트 크기 우선순위: 1000
- 최대 너비 우선순위: 750
4. 상대적 관계
오토 레이아웃은 절대적인 좌표(픽셀 단위)가 아닌 상대적인 관계를 기반으로 작동합니다. 이는 UI 요소가 화면 크기나 방향에 따라 유동적으로 위치를 조정하도록 만듭니다.
예:
- "버튼은 화면 중앙에 위치하고, 너비는 화면 너비의 50%이다."
- "이미지는 라벨 아래에 있으며, 라벨과의 거리는 10pt이다."
5. 적응형 레이아웃(Adaptive Layout)
오토 레이아웃은 다양한 화면 크기와 방향(세로/가로)에 따라 UI를 조정합니다. 이를 통해 하나의 레이아웃 설정으로 여러 기기를 지원할 수 있습니다.
핵심 목표
오토 레이아웃의 궁극적인 목적은 반응형 UI(Responsive UI)를 구현하는 것입니다. 이를 통해 개발자는 복잡한 화면 크기와 해상도를 직접 고려하지 않고도 다양한 기기에서 일관된 사용자 경험을 제공할 수 있습니다.

control을 누르고 연결시키면 outlet을 연결시킬 수 있음.

Outlets 세 개 Actions 하나
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var txtHeight: UITextField!
@IBOutlet weak var txtWeight: 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.
}
}
위 소스는 둘 다 값을 입력하지 않으면 다운 된다.

//
// ViewController.swift
// BMI_ljh
//
// Created by LimJongHoon on 11/13/24.
//
import UIKit
class ViewController: UIViewController {
// 키 입력 필드를 연결하는 아웃렛
@IBOutlet weak var txtHeight: UITextField!
// 몸무게 입력 필드를 연결하는 아웃렛
@IBOutlet weak var txtWeight: UITextField!
// BMI 계산 결과를 출력할 라벨
@IBOutlet weak var lblResult: UILabel!
// BMI 계산 버튼을 누르면 실행되는 함수
@IBAction func calcBmi(_ sender: UIButton) {
// 입력값 검증 (키와 몸무게가 비어있거나 유효하지 않을 경우 처리)
guard let heightText = txtHeight.text, !heightText.isEmpty, // 키 텍스트가 비어있는지 확인
let weightText = txtWeight.text, !weightText.isEmpty, // 몸무게 텍스트가 비어있는지 확인
let height = Double(heightText), // 키를 Double로 변환
let weight = Double(weightText), // 몸무게를 Double로 변환
height > 0, weight > 0 else { // 키와 몸무게가 0보다 큰지 확인
lblResult.textColor = .red // 에러 메시지를 빨간색으로 표시
lblResult.text = "⚠️ 키와 체중을 올바르게 입력하세요!" // 에러 메시지 출력
return // 잘못된 경우 함수 종료
}
// BMI 계산 (체중 / (키 * 키) * 10,000) kg/m² 단위
let bmi = weight / (height * height * 0.0001)
// BMI 값을 소수점 1자리로 포맷팅
let shortenedBmi = String(format: "%.1f", bmi)
// BMI 판정 및 관련 스타일 정의
var body = "" // 판정 결과 문자열
var color: UIColor = .black // 라벨 색상
var emoji = "" // 이모지 추가
// BMI에 따라 판정 및 스타일 결정
switch bmi {
case ..<18.5:
body = "저체중"
color = .blue // 저체중일 때 파란색
emoji = "🥶" // 저체중 이모지
case 18.5..<25:
body = "정상"
color = .green // 정상일 때 초록색
emoji = "😊" // 정상 이모지
case 25..<30:
body = "1단계 비만"
color = .orange // 1단계 비만일 때 주황색
emoji = "😐" // 1단계 비만 이모지
case 30..<40:
body = "2단계 비만"
color = .red // 2단계 비만일 때 빨간색
emoji = "😟" // 2단계 비만 이모지
default:
body = "3단계 비만"
color = .darkGray // 3단계 비만일 때 어두운 회색
emoji = "😱" // 3단계 비만 이모지
}
// 결과 라벨에 BMI 결과와 판정을 출력
lblResult.textColor = color // 판정에 따라 텍스트 색상 변경
lblResult.text = "\(emoji) BMI: \(shortenedBmi), 판정: \(body)" // 결과 출력
// 애니메이션 효과 (라벨 크기를 줄였다가 다시 키우기)
lblResult.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) // 라벨 크기를 80%로 축소
UIView.animate(withDuration: 0.5, // 애니메이션 지속 시간 0.5초
delay: 0, // 지연 시간 없음
usingSpringWithDamping: 0.5, // 스프링 효과
initialSpringVelocity: 1.0, // 초기 속도
options: .curveEaseInOut, // 부드러운 시작과 끝
animations: {
self.lblResult.transform = .identity // 원래 크기로 복구
})
}
override func viewDidLoad() {
super.viewDidLoad()
// 키와 몸무게 입력 필드 스타일 설정
configureTextField(txtHeight)
configureTextField(txtWeight)
// 결과 라벨 스타일 설정
configureResultLabel(lblResult)
}
// 텍스트 필드의 스타일을 설정하는 함수
func configureTextField(_ textField: UITextField) {
textField.layer.borderColor = UIColor.gray.cgColor // 테두리 색상: 회색
textField.layer.borderWidth = 2.0 // 테두리 두께: 2.0
textField.layer.cornerRadius = 5.0 // 모서리를 둥글게: 반경 5.0
textField.layer.masksToBounds = true // 텍스트 필드의 내용을 잘리지 않도록
}
// 결과 라벨의 스타일을 설정하는 함수
func configureResultLabel(_ label: UILabel) {
label.layer.cornerRadius = 10.0 // 모서리를 둥글게: 반경 10.0
label.layer.masksToBounds = true // 라벨의 내용을 잘리지 않도록
}
}

Tab Bar
**iOS Tab Bar Height (탭 바 높이)**에 대해 간단히 요약하면, iOS의 **탭 바(Tab Bar)**는 화면 하단에 위치하며, 앱 내에서 다양한 뷰(탭)를 전환할 수 있도록 도와주는 탐색 컨트롤러입니다. Tab Bar의 높이는 애플의 Human Interface Guidelines(HIG)에 따라 고정된 값 또는 디바이스의 상태에 따라 자동으로 결정됩니다.
탭 바의 기본 높이
- 표준 높이:
- 일반적으로 탭 바의 기본 높이는 49pt입니다.
- 모든 iPhone과 iPad에서 동일한 높이를 사용합니다.
- 안전 영역(Safe Area):
- iPhone X 이상(노치 디바이스)의 경우, 홈 인디케이터(Home Indicator)를 고려하여 **추가 여백(34pt)**이 포함됩니다.
- 이로 인해 탭 바의 총 높이는 **83pt (49pt + 34pt)**가 됩니다.
HIG 권장사항
- Apple은 탭 바의 사용자 경험을 일관되게 유지하기 위해 개발자가 탭 바의 높이를 수정하지 않도록 권장합니다.
- 탭 바의 콘텐츠와 아이템은 Apple의 시스템 기본 디자인 규칙을 따릅니다.
탭 바 높이 계산 방법 (코드로 확인)
탭 바의 높이를 확인하려면 아래와 같이 코드를 사용할 수 있습니다:
if let tabBarHeight = self.tabBarController?.tabBar.frame.height {
print("탭 바 높이: \(tabBarHeight)pt")
}
예상 출력:
- 일반 iPhone: 49.0pt
- iPhone X 이상: 83.0pt
탭 바 디자인 가이드
- 아이콘 및 텍스트 크기:
- 탭 바의 아이콘은 최대 75px(높이), 텍스트는 기본 12pt 폰트 사용.
- 컬러 및 스타일:
- Apple은 사용자가 탭 바의 배경색, 아이템 색상, 선택된 색상 등을 커스터마이즈할 수 있도록 허용.
- 탭 바 아이템 제한:
- 5개 이하의 아이템을 권장.
- 5개를 초과하면 "더보기" 탭으로 자동 생성.
탭 바 커스터마이징
탭 바의 스타일과 동작은 UITabBarController 및 UITabBar 클래스를 사용해 변경할 수 있습니다.
예제: 탭 바 배경 및 아이템 색상 변경
tabBarController?.tabBar.barTintColor = .white // 배경색
tabBarController?.tabBar.tintColor = .blue // 선택된 아이템 색상
tabBarController?.tabBar.unselectedItemTintColor = .gray // 선택되지 않은 아이템 색상
탭 바 높이 관련 개발 팁
- 자동 높이 조정: iOS가 디바이스 유형에 따라 탭 바 높이를 자동으로 설정하므로, 수동으로 높이를 변경하지 않는 것이 가장 안전합니다.
- Safe Area 고려: 탭 바의 콘텐츠를 배치할 때는 반드시 Safe Area를 고려해 콘텐츠가 잘리지 않도록 해야 합니다.
정리
- 기본 높이: 49pt
- 노치 디바이스(iPhone X 이상): 83pt (49pt + 34pt)
- Apple 권장사항: 탭 바 높이는 수정하지 말고, 기본 동작과 스타일 가이드를 따를 것.
탭 바는 iOS 앱 탐색의 핵심 요소이므로 Apple의 HIG를 따르는 것이 가장 중요합니다. 😊

**Manual Segue(메뉴얼 세그웨이)**와 **Relationship Segue(릴레이션쉽 세그웨이)**의 차이점
Manual Segue(메뉴얼 세그웨이)
- 사용 목적: 특정 사용자 동작(예: 버튼 클릭)에서 화면 전환을 수행할 때 사용.
- 작동 방식:
- 코드(performSegue) 또는 UI 요소(버튼, 제스처 등)와 연결하여 명시적으로 호출.
- 실행 시점: 버튼 클릭이나 특정 이벤트가 발생했을 때 실행.
- 필요한 설정:
- 스토리보드에서 Segue를 생성하고 Identifier를 지정해야 코드에서 호출 가능.
- Identifier 필요 여부: 필요함. (코드 호출 시 Identifier로 Segue를 식별.)
- 예제 사용 사례:
- 버튼 클릭 시 다음 화면으로 이동.
- 특정 조건에 따라 화면 전환을 동적으로 제어.
- 코드 호출 여부: performSegue(withIdentifier:sender:)로 호출 가능.
- 기능적 특징: 사용자 동작 기반으로 동적으로 화면 전환 가능.
Relationship Segue(릴레이션쉽 세그웨이)
- 사용 목적: 화면 간의 구조적 관계(예: 컨테이너 뷰 컨트롤러)를 정의할 때 사용.
- 작동 방식:
- 스토리보드에서 두 뷰 컨트롤러 간의 관계를 설정하여 자동으로 전환.
- 실행 시점: 앱 실행 시 초기화되거나 컨테이너 뷰 컨트롤러에 의해 자동 실행.
- 필요한 설정:
- UINavigationController 또는 UITabBarController와 같은 컨테이너 뷰 컨트롤러와 연결.
- Identifier 필요 여부: 필요하지 않음. (자동으로 처리되기 때문.)
- 예제 사용 사례:
- UINavigationController로 화면 계층 구조를 정의.
- UITabBarController의 탭 간 화면 전환.
- 코드 호출 여부: 코드 호출 없이 자동 작동.
- 기능적 특징: 앱 내의 화면 구조를 고정적으로 정의.
요약
- Manual Segue는 사용자의 특정 동작에 따라 명시적으로 화면 전환을 수행하는 데 사용됩니다. 주로 버튼 클릭이나 제스처에 반응하여 코드로 제어할 수 있습니다.
- Relationship Segue는 UINavigationController나 UITabBarController 같은 컨테이너 뷰 컨트롤러에서 화면 간의 관계를 정의하고, 앱 구조를 고정적으로 설정할 때 사용됩니다.