뷰에 적용된 제약 조건(constraints)을 기반으로 뷰 계층 구조에 있는 모든 뷰의 레이아웃을 자동으로 계산하여 그려줍니다.
다양한 제약 조건(leading, trailing, top, bottom, width, height 등)을 활용하여 뷰 간의 상대적인 위치와 크기를 정의합니다.
Interface Builder를 사용하여 시각적으로 제약 조건을 설정할 수 있고, 코드로도 제약 조건을 프로그래밍적으로 설정할 수 있습니다.
제약 조건의 우선순위 (Priority):
복합 제약 조건 (Compound Constraints):
핵심 !
조건을 어떻게 주느냐에 따라서 값을 계산하는데, 수식으로 나타내 보면
x,y는 서로 다른 뷰의 속성
a,b는 개발자가 지정하는 임의의 수
iOS가 모든 뷰의 4가지 값(= x,y의 위치/ 가로,세로 크기)를 구할 수 있도록,
개발자는 뷰와 뷰 사이의 상대적인 관계를 표현한 방정식(=조건)을 여러개 만들어서 전달합니다.
뷰의 속성

//조건 예시
// 높이를 40포인트로 지정한다.
View.height = 0.0 * NotAnAttribute + 40.0
// 두 버튼 사이의 간격을 8포인트 띄운다.
Button2.leading = 1.0 * Button1.trailing + 8.0
// 두 버튼의 왼쪽을 정렬한다.
Button1.leading = 1.0 * Button2.leading + 0.0
// 두 버튼의 너비를 똑같이 만든다.
Button1.width = 1.0 * Button2.width + 0.0
// 상위 뷰와 가운데 정렬을 한다.
View.centerX = 1.0 * Superview.centerX + 0.0
// 높이를 너비의 두배로 만든다.
View.height = 2.0 * View.width + 0.0
X축 기준으로 Leading, Trailing, Width, Center X 이렇게 4가지 속성이 있습니다.
이 중 2개가 정해져야 한다. (Y축도 동일)
테두리 속성 1개 (Leading or Trailing) + 테두리 속성 1개 (Leading or Trailing)
테두리 속성 1개 (Leading or Trailing) + 너비 속성 (Width)
테두리 속성 1개 (Leading or Trailing) + 중심축 속성 (Center X)
너비 속성 (Width) + 중심축 속성 (Center X)
// WriteViewController.swift 중 AutoLayout 부분
// 1. UI 요소들의 위치와 크기를 설정하는 메서드
private func setupUIConstraints() {
titleField.translatesAutoresizingMaskIntoConstraints = false
imageView.translatesAutoresizingMaskIntoConstraints = false
hashtagField.translatesAutoresizingMaskIntoConstraints = false
// 2.각 UI 요소들의 위치와 크기를 제약 조건을 통해 정의
NSLayoutConstraint.activate([
// titleField의 상단을 tableView의 safeAreaLayoutGuide의 상단에서 20 포인트 아래에 배치합니다.
titleField.topAnchor.constraint(equalTo: tableView.safeAreaLayoutGuide.topAnchor, constant: 20),
// titleField의 왼쪽을 view의 layoutMarginsGuide의 왼쪽에 정렬합니다.
titleField.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
//titleField의 오른쪽을 view의 layoutMarginsGuide의 오른쪽에 정렬합니다.
titleField.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
//titleField의 높이를 50 포인트로 고정합니다.
titleField.heightAnchor.constraint(equalToConstant: 50),
//imageView는 titleField 아래에 위치하고, 가로 너비와 세로 높이를 같게 설정하여 이미지를 정사각형 모양으로 유지합니다.
imageView.topAnchor.constraint(equalTo: titleField.bottomAnchor, constant: 20),
imageView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
imageView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor), // 이미지 높이와 너비 동일
//imagePickerButton은 imageView 아래 중앙에 배치됩니다.
imagePickerButton.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 20),
imagePickerButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
//hashtagField은 imagePickerButton 아래에 위치하고, 높이를 50 포인트로 고정합니다.
hashtagField.topAnchor.constraint(equalTo: imagePickerButton.bottomAnchor, constant: 10),
hashtagField.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
hashtagField.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
hashtagField.heightAnchor.constraint(equalToConstant: 50)
])
}
titleField, imageView, hashtagField을 비활성화:
각 UI 요소는 translatesAutoresizingMaskIntoConstraints를 false로 설정하여 기존의 자동으로 생성된 제약 조건을 해제합니다. 이렇게 하면 새로운 제약 조건을 수동으로 추가할 수 있게 됩니다.
NSLayoutConstraint.activate를 사용하여 여러 개의 제약 조건을 한 번에 활성화:
activate 메서드를 사용하여 여러 NSLayoutConstraint를 한 번에 활성화합니다. 이를 통해 여러 제약 조건을 간결하게 관리할 수 있습니다.
2015년 iOS 9에서 처음으로 등장, Stack View는 오토레이아웃을 편리하게 사용하도록 도와주기 위해 만들어졌습니다.
스택 뷰는 자동 레이아웃을 사용하여 정렬된 뷰의 위치와 크기를 조정합니다. 스택 뷰는 첫 번째와 마지막으로 정렬된 뷰를 스택 축을 따라 해당 가장자리에 정렬합니다. 수평 스택에서 이는 첫 번째로 정렬된 뷰의 앞쪽 가장자리가 스택의 앞쪽 가장자리에 고정되고 마지막으로 정렬된 뷰의 뒤쪽 가장자리가 스택의 뒤쪽 가장자리에 고정됨을 의미합니다. 수직 스택에서는 위쪽 및 아래쪽 가장자리가 각각 스택의 위쪽 및 아래쪽 가장자리에 고정됩니다.
-자동 레이아웃 관리: Stack View는 자식 뷰들의 위치와 크기를 자동으로 관리합니다. 이는 복잡한 레이아웃을 구현할 때 필요한 수많은 제약 조건을 직접 추가하거나 관리할 필요가 없다는 것을 의미합니다.
-방향성: Stack View는 수직(vertical) 또는 수평(horizontal) 방향으로 자식 뷰들을 배치합니다. 이는 --stack view의 axis 속성을 통해 설정할 수 있습니다.
- 배분 방식: Stack View는 공간을 어떻게 배분할지 결정하는 distribution 속성을 가지고 있습니다. 이 속성의 값에 따라 자식 뷰들이 동일한 크기를 가지거나, 동일한 공간을 차지하거나, 콘텐츠에 맞는 크기를 가지도록 할 수 있습니다.
- 정렬 방식: Stack View는 자식 뷰들을 어떻게 정렬할지 결정하는 alignment 속성을 가지고 있습니다. 이 속성의 값에 따라 자식 뷰들이 stack view의 leading, center, trailing 등에 정렬되거나, stack view를 꽉 채우도록 설정할 수 있습니다.
- 간격 설정: Stack View는 자식 뷰들 사이의 간격을 설정하는 spacing 속성을 가지고 있습니다. 이 속성을 사용하면 자식 뷰들 사이의 공간을 쉽게 조절할 수 있습니다.
- 자동 적응: Stack View는 화면 크기나 방향이 변경될 때 자동으로 적응합니다. 예를 들어, iPhone에서 세로 모드에서 가로 모드로 변경될 때, Stack View는 자식 뷰들의 배치를 자동으로 조절하여 최적의 레이아웃을 유지합니다.
stackView.axis = .horizontal //스택 뷰의 방향을 수직 또는 수평으로 정의합니다.
stackView.distribution = .fillEqually //축을 따라 뷰의 레이아웃을 정의합니다.
stackView.alignment = .center //스택 뷰의 축에 수직인 뷰의 레이아웃을 정의합니다.
stackView.spacing = 10 //인접한 뷰 사이의 공간을 정의합니다.
//ReportView.swift StackView 사용 부분
override init(frame:CGRect) {
super.init(frame:frame)
// UIStackView를 생성
let stackView = UIStackView()
stackView.axis = .vertical // 수직 스택뷰로 설정 (버튼들이 위 아래로 쌓이게 됨)
stackView.alignment = .center // 중앙 정렬
stackView.spacing = 40 // 버튼 사이의 간격 설정
self.backgroundColor = UIColor.white
// 버튼들을 UIStackView에 추가
stackView.addArrangedSubview(sbsButton)
stackView.addArrangedSubview(kbsButton)
stackView.addArrangedSubview(mbcButton)
// UIStackView를 view에 추가
addSubview(stackView)
// UIStackView의 Auto Layout 제약 조건 설정 (가운데 정렬)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalToConstant: 300).isActive = true // 원하는 너비로 설정
stackView.heightAnchor.constraint(equalToConstant: 230).isActive = true // 원하는 높이로 설정
}
//ReportviewController.swift AutoLayout 사용 부분
override func viewDidLoad() {
super.viewDidLoad()
// reportView를 화면에 추가하고 크기를 설정
view.addSubview(reportView)
reportView.translatesAutoresizingMaskIntoConstraints = false
reportView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
reportView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
reportView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
reportView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
// textView를 화면에 추가하고 크기를 설정
view.addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
ReportView는 StackView로 구현하고, TextView와 ReportViewController에서는 AutoLayout을 사용하여 정의하였습니다.