본문 바로가기

iOS 개발/SwiftUI

[iOS/SwiftUI] Alignment Guides, Custom Alignment

Alignment guides

부모 View 의 정렬 규칙이 아닌 자식 View 각각의 정렬 규칙을 따르고 싶을 때 사용한다. Stack 에 속한 View 들은 각각의 Alignment guide 를 갖는다. 

 

Stack 의 종류에 따라 수평, 수직의 중간 지점에 대한 정보가 계산되는데, 각 View 들은 자신이 속한 Stack의 중간 지점에 자신의 Alignment guide 를 맞춘다. 즉, 기본적으로 Center alignment 가 적용된다.

 

그런데 Stack 에 속한 일부 View 에 대해 다른 정렬 기준을 적용하고 싶다면 alignmentGuide modifier 를 사용하면 된다.

 

HStack {
    Text("🌧")
        .alignmentGuide(VerticalAlignment.center) { _ in -20 }
    Text("Rain & Thunderstorms")
        .border(Color.gray)
    Text("⛈")
        .alignmentGuide(VerticalAlignment.center) { _ in 20 }
        .border(Color.gray)
}


HStack {
    ScaledImage("Trig")
    ScaledImage("Patterns")
      .alignmentGuide(VerticalAlignment.center) { $0.height }
    Text("Learn SwiftUI layout!")
      .alignmentGuide(VerticalAlignment.center) { $0[.top] }
}

 

첫 번째 HStack 에서 이모티콘들은 HStack 의 수직 중간 지점에서 20 만큼 떨어진 곳에 위치한다. 

 

두 번째 HStack 에서 두 번째 이미지는 HStack 의 수직 중간 지점에 높이 만큼 위로 이동한 위치를 맞추고(중간 지점에서부터 이미지가 시작되는데 높이 만큼 위로 이동했으므로 bottom 에 맞추게 된다.), 세 번째 텍스트는 자신의 top 을 HStack 의 수직 중간 지점에 맞춘다.

 

두 번째 HStack 의 정렬 상태

Custom alignments

서로 다른 Stack 에 있는 View 들을 기준으로 정렬하고 싶을 때 유용하다.

 

struct ContentView: View {
  var body: some View {
    HStack(alignment: .midAccountAndName) {
    // Align these two views so their centers are both on the .midAccountAndName guide”
      VStack {
        Text("@atj")
          .alignmentGuide(.midAccountAndName) { $0[VerticalAlignment.center] }
        Image(systemName: "swift")
          .resizable()
          .frame(width: 64, height: 64)
      }
      
      VStack {
        Text("Full name:")
        Text("AHN TAE JEONG")
          .font(.largeTitle)
          .alignmentGuide(.midAccountAndName) { $0[VerticalAlignment.center] }
      }
    }
  }
}

extension VerticalAlignment {
  enum MidAccountAndName: AlignmentID {
    static func defaultValue(in context: ViewDimensions) -> CGFloat {
      context[.top]
    }
  }
  static let midAccountAndName = VerticalAlignment(MidAccountAndName.self)
}

 

일반적인 방법으론 서로 다른 Stack 에 있는 두 View 에 대해 동일한 정렬 기준을 적용하기 힘들다. 정렬 기준을 사용자가 정의한 뒤, 원하는 View 를 기준에 맞게 정렬한다.