관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - SwiftUI] GeometryReader, GeometryProxy 사용 방법 (뷰 레이아웃) 본문

iOS 기본 (SwiftUI)

[iOS - SwiftUI] GeometryReader, GeometryProxy 사용 방법 (뷰 레이아웃)

jake-kim 2022. 10. 23. 23:09

목차) SwiftUI의 기본 - 목차 링크

 

*초록색 뷰를 파란색뷰 오른쪽 하단에 위치시키는 방법?

-> 아래에서 알아볼 GeomettryReader를 사용

GeometryReader, GeometryProxy 란?

  • 뷰의 Container라고 생각하면 되고, 인수로 사용할 수 있는 GeometryProxy가 존재
    • GeometryProxy란 좌표와 사이즈 값을 가지고 있는 역할
    • 즉, 컨테이너뷰에 관련하여 좌표를 구하고 싶을때나 컨테이너뷰의 크기를 알고 싶은 경우, proxy로 사용
struct ContentView: View {
  var body: some View {
    VStack {
      Text("Jake iOS 앱 개발 알아가기")
      GeometryReader { proxy in
      
      }
    }
  }
}
  • GeometryProxy 사용 방법
    • size, safeAreaInsets, frame 값을 얻기가 가능
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public struct GeometryProxy {
    public var size: CGSize { get }
    public subscript<T>(anchor: Anchor<T>) -> T { get }
    public var safeAreaInsets: EdgeInsets { get }
    public func frame(in coordinateSpace: CoordinateSpace) -> CGRect
}
  • frame(in:) 메소드는 CoordinateSpace가 존재
    • global: 디바이스의 스크린에 맞춘 좌표
    • local: 가장 가까운 부모 뷰와의 상대적인 좌표
    • named: 어떤 뷰에든지 .coordinateSpace(name: "someName")이름을 등록할수 있는데, 등록한 뷰에 관한 상대적인 좌표를 구하고 싶을때 사용

https://developer.apple.com/documentation/swiftui/coordinatespace

  •  코드
var body: some View {
  VStack {
    Text("Jake iOS 앱 개발 알아가기")
    
    GeometryReader { proxy in
      Rectangle()
        .foregroundColor(.blue)
        .onAppear {
          print("size = \(proxy.size)") // (390.0, 730.357)
          print("safeAreaInsets = \(proxy.safeAreaInsets)") // EdgeInsets(top: 0.0, leading: 0.0, bottom: 34.0, trailing: 0.0)
          
          // global, local, named
          print("global = \(proxy.frame(in: .global))") // (0.0, 79.64241536458333, 390.0, 730.357)
          print("local = \(proxy.frame(in: .local))") // (0.0, 0.0, 390.0, 730.357)
          print("name = \(proxy.frame(in: .named("OuterVStack")))") // (0.0, 32.64241536458333, 390.0, 730.357)
        }
  }
  .coordinateSpace(name: "OuterVStack")
}

proxy를 이용하여 초록색 뷰 우측하단에 놓기

  • 파란 뷰 준비
struct ContentView: View {
  var body: some View {
    VStack {
      Text("Jake iOS 앱 개발 알아가기")
      
      GeometryReader { proxy in
        Rectangle()
          .foregroundColor(.blue)
      }
    }
  }
}

 

  • .overay를 사용하여 파란 뷰 위에 초록색 뷰를 얹고, proxy의 size, frame값을 이용하여 배치
GeometryReader { proxy in
  Rectangle()
    .foregroundColor(.blue)
    .onAppear {
      print("size = \(proxy.size)")
      print("safeAreaInsets = \(proxy.safeAreaInsets)")
      
      // global, local, named
      print("global = \(proxy.frame(in: .global))")
      print("local = \(proxy.frame(in: .local))")
      print("name = \(proxy.frame(in: .named("OuterVStack")))")
    }
    .overlay(
      Rectangle()
        .foregroundColor(.green)
        .frame(width: proxy.size.width/2, height: proxy.size.height/2)
        .offset(
          x: proxy.frame(in: .local).minX+proxy.size.width/2/2,
          y: proxy.frame(in: .local).minY+proxy.size.height/2/2
        )
    )
}

* 전체 코드: https://github.com/JK0369/ExGeometryReader

 

* 참고

https://developer.apple.com/documentation/swiftui/coordinatespace

https://developer.apple.com/documentation/swiftui/geometryproxy

https://developer.apple.com/documentation/swiftui/geometryreader

Comments