swiftUI를 사용하다보면 View의 사이즈를 가져와야 할 경우가 종종 있다

코드 자체는 생각보다 간단하다

@Binding을 사용하여 가져오기

struct GetViewSizeModifier: ViewModifier {
    @Binding var size: CGSize
    
    func body(content: Content) -> some View {
        content
            .background(
                GeometryReader { geo -> Color in
                    DispatchQueue.main.async {
                        size = geo.size
                    }
                    return Color.clear
                }
            )
    }
}

extension View {
    func getViewSize(_ size: Binding<CGSize>) -> some View {
        self.modifier(GetViewSizeModifier(size: size))
    }
}

//사용
import SwiftUI

struct GetViewSizeView: View {
    
    @State private var size: CGSize = .zero
    
    var body: some View {
        VStack {
            VStack {
                Text("이곳의 뷰 높이를 가져와 봅니다")
                    .padding(.vertical, 40)
            }
            .background(.gray)
            .getViewSize($size)
        }
        .onChange(of: size) {
            print($0)
        }
    }
}

Closer를 사용해서 가져오기

struct GetViewSizeCloserModifier: ViewModifier {
    
    let handler: (CGSize) -> Void
    
    func body(content: Content) -> some View {
        content
            .background(
                GeometryReader { geo -> Color in
                    DispatchQueue.main.async {
                        handler(geo.size)
                    }
                    return Color.clear
                }
            )
    }
}

extension View {
    func getViewSize(perform handler: @escaping (CGSize) -> Void) -> some View {
        self.modifier(GetViewSizeCloserModifier(handler: handler))
    }
}

//사용
import SwiftUI

struct ExampleGetViewSizeView: View {
    
    var body: some View {
        VStack {
            VStack {
                Text("이곳의 뷰 높이를 가져와 봅니다")
                    .padding(.vertical, 40)
            }
            .background(.gray)
            .getViewSize {
                print($0)
            }
        }
    }
}