๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS/SwiftUI

[SwiftUI] GeometryReader๋ž€? (feat. GeometryProxy,CoordinateSpace)

by Fomagran ๐Ÿ’ป 2022. 4. 4.
728x90
๋ฐ˜์‘ํ˜•

 

์•ˆ๋…•ํ•˜์„ธ์š” Foma ๐Ÿ’ป ์ž…๋‹ˆ๋‹ค!

 

์˜ค๋Š˜์€ SwitUI๋ฅผ ์ด์šฉํ•ด์„œ Layout์„ ์žก์„ ๋•Œ ์•„์ฃผ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” GeometryReader์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


GeometryReader๋ž€?

 

์ด๋ฆ„์„ ์ง์—ญํ•˜๋ฉด Geometry๋Š” ๊ธฐํ•˜ํ•™์„ ๋‚˜ํƒ€๋‚ด๋‹ˆ๊น, ๊ธฐํ•˜ํ•™์ ์ธ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ฝ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

 

 

๊ณต์‹ ๋ฌธ์„œ์—๋„ ์ด๋ฆ„์„ ์ง์—ญํ•œ ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๊ฒŒ "์ปจํ…์ธ ์˜ ํฌ๊ธฐ์™€ ์œ„์น˜๋ฅผ ํ•จ์ˆ˜๋กœ ๋‚˜ํƒ€๋‚ด๋Š” ์ปจํ…Œ์ด๋„ˆ ๋ทฐ์•ผ!" ๋ผ๊ณ  ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

 

 

GeometryReader๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ปจํ…์ธ ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ GeometryProxy๋ฅผ ์ด์šฉํ•ด์„œ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 


GeometryProxy๋ž€?

 

๊ทธ๋ ‡๋‹ค๋ฉด GeometryProxy๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

 

์šฐ์„  Proxy์˜ ๋œป์€ ๋ฌด์—‡์ธ๊ฐ€๋ฅผ ๋Œ€์‹  ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

 

๊ณ ๋กœ Geometry + Proxy๋Š” ๊ธฐํ•˜ํ•™์ ์ธ ์ •๋ณด๋ฅผ ๋Œ€์‹  ๋‚˜ํƒ€๋‚ด์ฃผ๋Š” ๋ฌด์—‡์ด๋ผ๊ณ  ํ•ด์„ํ•  ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”.

 

 

GeometryReader์˜ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์•„๋ž˜๋กœ ๋‚ด๋ฆฌ๋ฉด See Also๋กœ GeometryProxy๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๊ณต์‹ ๋ฌธ์„œ์—๋Š” "์ปจํ…Œ์ด๋„ˆ ๋ทฐ์˜ ์ขŒํ‘œ๋‚˜ ํฌ๊ธฐ๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ" ์ด๋ผ๊ณ  ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

 

 

์ฆ‰, GeometryReader๋Š” ๊ธฐํ•˜ํ•™์ ์ธ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ ๋ทฐ ์ž์ฒด์ด๊ณ  ํ•ด๋‹น ์ •๋ณด๋ฅผ ์–ป์–ด๋‚ด๊ธฐ ์œ„ํ•ด์„  GeometrryProxy๋ฅผ ์ด์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด์ฃ .

 

GeometryProxy๋ฅผ ํ†ตํ•ด์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ ์•„๋ž˜์™€ ๊ฐ™์ด frame(in:), size, safeAreaInsets๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ณดํ†ต frame(in:) ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ขŒํ‘œ๊ฐ’์„ ๊ตฌํ•˜๊ณ , size๋ฅผ ์ด์šฉํ•˜์—ฌ ํฌ๊ธฐ๋ฅผ, safeAreaInsets๋ฅผ ํ†ตํ•ด ์ปจํ…Œ์ด๋„ˆ ๋ทฐ์˜ safe area์˜ ๊ฐ€์žฅ ์ž๋ฆฌ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

 

์œ„์—์„œ ์ด๋ก ์„ ์‚ดํŽด ๋ณด์•˜์œผ๋‹ˆ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์“ฐ์ด๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์ด VStack๊ณผ HStack๊ณผ Spacer()๋ฅผ ์ด์šฉํ•˜์—ฌ GeometryReaderDetailView๋ฅผ ๋ฐฐ์น˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

GeometryReaderView

 

struct GeometryReaderView: View {
    var body: some View {
        VStack {
            Spacer()
            HStack {
            GeometryReaderDetailView()
                Spacer()
            }
        }
    }
}

 

GeometryReaderDetailView

 

struct GeometryReaderDetailView: View {
    var body: some View {
       Rectangle()
    }
}

 

์ด๋ ‡๊ฒŒ ๋ฐฐ์น˜ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ด์™€ ๊ฐ™์ด ๋‚˜ํƒ€๋‚˜๋Š” ์ด์œ ๋Š” SwiftUI์—์„  Content๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ํ•ด๋‹น ํฌ๊ธฐ๋ฅผ ์˜ˆ์ธกํ•˜์—ฌ ์„ค์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

 

์œ„์™€ ๊ฐ™์€ ํ™”๋ฉด์—์„œ ๊ฒ€์ •์ƒ‰ ์‚ฌ๊ฐํ˜•์˜ ํฌ๊ธฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

 

๋ฐ”๋กœ ์—ฌ๊ธฐ์„œ GeometryReader๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


Size

 

์•„๋ž˜์™€ ๊ฐ™์ด ํฌ๊ธฐ๋ฅผ ์•Œ์•„๋‚ด๊ณ  ์‹ถ์€ View๋ฅผ GeometryReader๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค.

 

struct GeometryReaderView: View {
    var body: some View {
        VStack {
            Spacer()
            HStack {
                GeometryReader { proxy in
                    GeometryReaderDetailView()
                        .onAppear {
                            print(proxy.size)
                        }
                }
                Spacer()
            }
        }
    }
}

 

์•„๋ž˜์™€ ๊ฐ™์ด GeometryReaderDetailView์˜ width์™€ height๋ฅผ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


Frame

 

์ด์ œ ํฌ๊ธฐ๋ฅผ ์•Œ์•„๋ƒˆ์œผ๋‹ˆ ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์–ด๋””์— ์œ„์น˜ํ•ด ์žˆ๋Š”์ง€ ์ขŒํ‘œ๋ฅผ ๊ตฌํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ขŒํ‘œ๋ฅผ ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด์„  proxy์˜ frame(in:)์„ ์ด์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ์š”.

 

์ด 3๊ฐ€์ง€ coordinatespace๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.


CoordinateSpace๋ž€?

 

๊ณต์‹ ๋ฌธ์„œ์—” "๋ทฐ์˜ ์ขŒํ‘œ์— ์ด๋ฆ„์„ ์ •ํ•ด์„œ ๋‹ค๋ฅธ ์ฝ”๋“œ์—์„œ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ๋ฉ”์„œ๋“œ" ๋ผ๊ณ  ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

 

 

์ฆ‰, ๋ทฐ์˜ ์œ„์น˜๋ฅผ '์–ด๋Š ๊ธฐ์ค€์œผ๋กœ ๋ฐ”๋ผ๋ณผ ๊ฒƒ์ธ๊ฐ€'๋ฅผ ์ •ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

 

์ด๋ฏธ ์ •ํ•ด์ง„ ๊ธฐ์ค€์ด global,local์ด ์กด์žฌํ•˜๋ฉฐ ์›ํ•˜๋Š” ๋ทฐ๋ฅผ named๋ฅผ ํ†ตํ•ด์„œ ์ด๋ฆ„ ๋ถ™์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

1. global

 

global์€ ์ „์ฒด ํ™”๋ฉด์—์„œ ๋ฐ”๋ผ๋ณด์•˜์„ ๋•Œ์˜ ์œ„์น˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

2. local

 

ํ˜„์žฌ ์ง์ ‘์ ์œผ๋กœ ๊ฐ์‹ธ์ ธ ์žˆ๋Š” ๋ทฐ์—์„œ ๋ฐ”๋ผ๋ณด์•˜์„ ๋•Œ์˜ ์œ„์น˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

3. named

 

์›ํ•˜๋Š” ๋ทฐ์— ์ด๋ฆ„์„ ๋ถ™์ด๊ณ  ํ•ด๋‹น ๋ทฐ์—์„œ ๋ฐ”๋ผ๋ณด์•˜์„ ๋•Œ ์œ„์น˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.


๋‹ค์‹œ GeometryProxy์˜ frame(in:)์œผ๋กœ ๋Œ์•„์™€์„œ ์„ค๋ช…ํ•˜๋ฉด,

 

GeometryReaderDetail๋ทฐ์˜ ์œ„์น˜๋ฅผ ์–ด๋Š ๋ทฐ ๊ธฐ์ค€์œผ๋กœ ๋ฐ”๋ผ๋ณผ ๊ฒƒ์ธ์ง€๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ์š”.

 

์•„๋ž˜์™€ ๊ฐ™์ด global - ๋ทฐ ์ „์ฒด์—์„œ ์œ„์น˜ , local - GeotryReader์—์„œ์˜ ์œ„์น˜ , named("HStack") HStack์—์„œ ์œ„์น˜๋ฅผ ์ถœ๋ ฅํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 var body: some View {
        VStack {
            Spacer()
            HStack {
                Spacer()
                GeometryReader { proxy in
                    GeometryReaderDetailView()
                        .onAppear {
                            print(proxy.frame(in: .global))
                            print(proxy.frame(in: .local))
                            print(proxy.frame(in: .named("HStack")))
                        }
                }
            }
            .coordinateSpace(name: "HStack")
        }
    }

 

 

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ถœ๋ ฅ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 


SafeAreaInsets

 

GeometryProxy์—์„  ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ ๋ทฐ์˜ safeareaInsets์˜ ์ •๋ณด๋„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

 

 

์•„๋ž˜์™€ ๊ฐ™์ด View๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  safeAreaInsets๋ฅผ ์ถœ๋ ฅํ•˜๋ฉด

 

  var body: some View {
        VStack {
            HStack {
                GeometryReader { proxy in
                    GeometryReaderDetailView()
                        .onAppear {
                            print(proxy.safeAreaInsets)
                        }
                }
            }
        }
        
    }

 

 

 

์œ„์—์„  safearea๊ฐ€ ์œ„์ชฝ๊ณผ ์•„๋ž˜์ชฝ๋งŒ ์ ์šฉ์ด ๋˜์–ด ์žˆ์œผ๋‹ˆ top,bottom์˜ ๊ฐ’๋งŒ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋งŒ์•ฝ VStack์— safearea๋ฅผ ๋ฌด์‹œํ•˜๋„๋ก ํ•˜๊ฒŒ ๋˜๋ฉด

 

    VStack {
            HStack {
                GeometryReader { proxy in
                    GeometryReaderDetailView()
                        .onAppear {
                            print(proxy.safeAreaInsets)
                        }
                }
            }
        }
        .ignoresSafeArea(.all)

 

์•„๋ž˜์™€ ๊ฐ™์ด safearea๊ฐ€ ์œ„์ชฝ๊ณผ ์•„๋ž˜์ชฝ์ด ๋ฌด์‹œ๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

๊ณ ๋กœ ์ถœ๋ ฅ๋˜๋Š” ๊ฐ’๋„ top๊ณผ bottom์ด 0์œผ๋กœ ๋ณ€ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


์˜ค๋Š˜์€ ์ด๋ ‡๊ฒŒ GeometryReader์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์•˜๋Š”๋ฐ์š”.

 

์ด๊ฒƒ์„ ํ†ตํ•ด์„œ ์ข€ ๋” ์„ธ๋ถ€์ ์ด๊ณ  ์ •๊ตํ•œ ๋ ˆ์ด์•„์›ƒ ์ž‘์—…์„ SwiftUI์—์„œ ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

 

ํ˜น์‹œ๋ผ๋„ ํ‹€๋ฆฐ ์ ์ด ์žˆ๊ฑฐ๋‚˜ ์ง€์ ํ•ด์ฃผ์‹ค ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!


Reference

 

 

Apple Developer Documentation

 

developer.apple.com

 

 

Understanding frames and coordinates inside GeometryReader - a free Hacking with iOS: SwiftUI Edition tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€