
👋 들어가기 전

설 연휴 동안 UIKit 감각을 찾기위해 여러가지 끄적거리고 있었는데 UIStackView의 속성을
한번 정리해보려고 한다.
항상 급할 때마다 블로그에서 시각자료로 보고 결정했는데
이번에는 내 방식대로 정리한 후 내꺼를 보는게 더 나을 것 같다. ㅋㅋㅋ
시각적으로 쉽게 이해하기 위해 axis는 horizontal로 살펴보자.
설명 중 파란색 괄호는 axis를 .vertical로 변경했을 때 영향을 받는 속성으로 약속하자
✊기본 세팅
기본은 horizontal axis의 UIStackView에 4개의 UILabel을 넣은 형태다.
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.spacing = 5
stackView.distribution
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(stackView)
stackView.setHorizontal(view: view, constant: .zero)
stackView.setCenterY(view: view)
stackView.setHeight(200)
stackView.backgroundColor = .white
zip(["First", "Secnod", "Third", "Fourth"],
[UIColor.red, UIColor.orange, UIColor.blue, UIColor.green]
).forEach { order, color in
let label = UILabel()
label.text = order
label.backgroundColor = color
stackView.addArrangedSubview(label)
}
}
☝️Alignment
정의
alignment는 현재 UIStackView axis의 수직 축의 레이아웃을 말한다.
즉, 현재는 vertical 요소들을 말한다.
각 속성들의 설명과 결과 사진을 살펴보자.
1. fill (default value)
동작 방식
가능한 UIStackView 높이(너비)에 꽉 채운다.
결과
UILabel의 높이를 따로 지정해주지 않았지만 UIStackView 높이 200에 늘어났다.

2. leading
동작 방식
subview들이 stackView의 top(leading) 방향으로 정렬
결과
stackView top쪽에 정렬 됨

3. trailing
동작 방식
subview들이 stackView의 bottom(trailing)방향으로 정렬
결과
stackView bottom쪽에 정렬 됨

4. center
동작 방식
subview들이 stackView의 centerY(centerX)으로 정렬
결과
stackView centerY쪽에 정렬 됨

✌️distribution
들어가기 전
위 속성을 알기위해서는 뷰 레이아웃에 적용하는 priority를 먼저 알야아한다.
해당 내용은 https://hamp.tistory.com/151 이 링크를 통해 살펴보면 된다.
정리하면 hugging은 값이 높을수록 늘어나려는 저항이 커짐(안 커질라고함)
compression resistance 값이 높을수록 작아지려는 저항이 커짐(안 작아질려고함)
정의
alignment는 현재 axis의 수직 축의 레이아웃을 담당했다면 distribution은
현재 axis를 따른 레이아웃을 의미한다.
1. fill (default value)
동작 방식
가능한 UIStackView 너비로 요소들을 꽉 채우려한다.
이러면 경우가 2가지로 나뉜다.
if 스택뷰크기 > subviews크기일 경우
- hugging priority가 작은 애들부터 커지게 만든다.
if 스택뷰크기 < subviews크기일 경우
- compression resistance priority가 낮은 애들부터 작아지게 만든다.
결과
if color == .red {
label.setContentHuggingPriority(.required, for: .horizontal)
}
if color == .orange {
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
}
if color == .green {
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
}
print(label.contentHuggingPriority(for: .horizontal))
다음과 같이 hugging 우선순위를 지정했을 때, blue와 green은 우선순위가 같다.

내가 priority를 공부했을 때는 우선순위가 같을 때 왼쪽이 우선이라고 생각했으므로
green이 늘어나야한다고 생각했다.

그러나 결과는 blue가 늘어났다.
스택뷰는 나중에 넣은게 우선순위가 동일할 때 우선시 된다는 특징이 있는 것 같다.
2. fillEqually
동작 방식
모든 subview가 동일한 크기를 갖는다. 너비가 긴건 작게, 작은건 크게 늘린다.
결과
위에 hugging 우선순위를 그대로 유지했음에도 모두 같은 크기를 갖게 바뀐다.

3. fillProportionally
동작 방식
subview들의 intrinsicContentSize 비율을 유지하며 조절
결과
위에 hugging 우선순위를 그대로 유지했음에도 모두 같은 크기를 갖게 바뀐다.
왼쪽은 모두 같은 compressionResistance Priority일 때고
오른쪽은 green을 제외한 모든 label을 priority를 required로 올려봤다.
일단 priority를 먼저 지킨 후 intrinsicContentSize 비율에 따라 조절하는 것 같다.


4. eqaulSpacing
동작 방식
모든 subview간의 간격을 동일하게 배치한다.
위 fillEqually와 헷갈리지 않게 조심하자 fillEqually는 subview의 크기가 동일한 것
내부 subview 크기를 조절하지 않고 사이 간격을 조절
만약 subview의 크기가 stackview를 넘어 어쩔 수 없이 subview의 크기를 조절해야할 때는
compression resistance priority를 기준으로 작게 만든다.
마찬가지로 우선순위가 같을 경우 앞쪽 것이 변형된다.
결과
spacing을 15로 변경해봤다. subview가 4개니 spacing 3개가 잘나옴
여기서 spacing은 최소 값이 15가 되는 것
15로 설정해도 동일한 spacing 간격을 위해 15보다 커야하면 간격이 커질 수 있음

5. eqaul Centering
동작 방식
subview들의 중심이 양 옆의 중심까지의 거리가 같도록 조절
만약 조절한 후 너비가 스택뷰 너비보다 크다면 spacing을 줄이고
최소 spacing보다 작아져야한다면 compression resistance priority가 낮은 것부터 줄여준다.
결과
결과를 보니깐 중심으로부터 거리가 갖게 하기위해 spacing을 조절했음에도
불구하고 너비가 여전히 동일한 priority에도 불구하고 가장 앞에있는 뷰가
줄어든 것을 볼 수 있다.

😀 소감 및 마무리
실제로 속성을 변경하면서 차례 차례 비교해보니 생각보다 별거 없었다 ??
이전에 공부했던 intrinsicContentSize와 priority들의 지식들이 학습 속도를 더욱 빠르게 해줬다.
앞으로 UIStackView를 쓸 때 이 포스팅을 많이 찾을 것 같다.
출처
'iOS > UIKit' 카테고리의 다른 글
PhotoPicker 최적화하기 (4) | 2024.12.29 |
---|---|
Priority (1) | 2024.12.15 |
IntrinsicContentSize (1) | 2024.12.15 |
Auto Layout이란 (0) | 2024.12.15 |
특정 시기에 아이콘 자동 변경하기 (0) | 2024.10.26 |