SwiftUI alignmentGuide와 Custom Layout 완벽 이해
SwiftUI Layout의 내부 동작(Propose → Size → Place)을 이해했다면, 다음 단계는 정렬(alignment)을 직접 제어하는 방법입니다.
기본 Stack만으로 해결되지 않는 레이아웃은 alignmentGuide와 Custom Layout으로 해결할 수 있습니다.
1. alignment란 무엇인가?
SwiftUI에서 alignment는 부모가 자식 뷰를 어디 기준으로 정렬할지를 의미합니다.
HStack(alignment: .top) {
Text("A")
Text("B")
}
위 코드에서 HStack은 자식 뷰들을 top 기준으로 정렬합니다.
2. alignmentGuide란?
alignmentGuide는 뷰가 자신의 정렬 기준을 직접 정의할 수 있게 해주는 기능입니다.
Text("Hello")
.alignmentGuide(.leading) { d in
d[.trailing]
}
이 코드는 "leading 정렬 기준을 trailing 기준으로 사용"하겠다는 의미입니다.
즉, alignmentGuide는 다음과 같이 동작합니다.
- 부모가 alignment 기준 요청
- 자식이 alignmentGuide로 응답
3. alignmentGuide 내부 동작
alignmentGuide는 결국 좌표 값을 재정의하는 것입니다.
d[.leading]→ 기본 leading 위치d[.trailing]→ 기본 trailing 위치
이 값을 변경하면 부모의 배치 기준이 달라집니다.
4. 실전 예제
텍스트 기준선 맞추기
HStack(alignment: .firstTextBaseline) {
Text("Hello")
.font(.largeTitle)
Text("World")
}
폰트 크기가 달라도 baseline 기준으로 정렬됩니다.
커스텀 정렬 만들기
extension VerticalAlignment {
private enum CustomAlignment: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
d[.center]
}
}
static let custom = VerticalAlignment(CustomAlignment.self)
}
HStack(alignment: .custom) {
Text("A")
.alignmentGuide(.custom) { d in d[.bottom] }
Text("B")
.alignmentGuide(.custom) { d in d[.top] }
}
각 뷰가 서로 다른 기준으로 정렬됩니다.
5. Custom Layout이 필요한 이유
alignmentGuide로도 해결이 안 되는 경우가 있습니다.
- Grid처럼 복잡한 배치
- Flow Layout (줄바꿈)
- 동적 위치 계산
이럴 때 사용하는 것이 Layout protocol입니다.
6. Layout 프로토콜 기본 구조
struct CustomLayout: Layout {
func sizeThatFits(
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()
) -> CGSize {
return CGSize(width: 100, height: 100)
}
func placeSubviews(
in bounds: CGRect,
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()
) {
for subview in subviews {
subview.place(at: bounds.origin, proposal: proposal)
}
}
}
여기서 중요한 역할은 다음과 같습니다.
- sizeThatFits → 전체 크기 계산
- placeSubviews → 자식 위치 배치
7. Flow Layout 예제
줄바꿈되는 레이아웃을 직접 구현할 수 있습니다.
struct FlowLayout: Layout {
func sizeThatFits(proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()) -> CGSize {
var width: CGFloat = 0
var height: CGFloat = 0
for subview in subviews {
let size = subview.sizeThatFits(proposal)
width = max(width, size.width)
height += size.height
}
return CGSize(width: width, height: height)
}
func placeSubviews(in bounds: CGRect,
proposal: ProposedViewSize,
subviews: Subviews,
cache: inout ()) {
var y: CGFloat = bounds.minY
for subview in subviews {
let size = subview.sizeThatFits(proposal)
subview.place(
at: CGPoint(x: bounds.minX, y: y),
proposal: proposal
)
y += size.height
}
}
}
8. 언제 어떤 것을 써야 할까?
| 상황 | 사용 방법 |
|---|---|
| 단순 정렬 | alignment |
| 정렬 기준 변경 | alignmentGuide |
| 완전히 새로운 레이아웃 | Layout protocol |
9. 결론
SwiftUI Layout을 깊이 있게 사용하려면 다음 단계로 확장해야 합니다.
- alignment → 기본 정렬
- alignmentGuide → 기준 재정의
- Layout → 완전 커스터마이징
이 세 가지를 이해하면 복잡한 UI도 제약 없이 구현할 수 있습니다.
다음 단계에서는 SwiftUI Layout 성능 최적화를 다루면 실무 활용도가 더욱 높아집니다.
'IT' 카테고리의 다른 글
| SwiftUI NavigationStack 완전 정복 (push, pop, 딥링크까지 한 번에 해결) (0) | 2026.04.03 |
|---|---|
| SwiftUI Layout 성능 최적화 완벽 가이드 (0) | 2026.04.03 |
| SwiftUI Layout 시스템 내부 동작 완벽 이해 (0) | 2026.04.03 |
| AutoLayout vs SwiftUI Layout 시스템 완벽 비교 (0) | 2026.04.03 |
| iOS trailing vs trailingAnchor 차이 완벽 정리 (0) | 2026.04.03 |