apple/SwiftUI & Combine

[SwiftUI] GeometryReader

lgvv 2022. 5. 19. 00:49

GeometryReader

 

✅ GeometryReader에 대해서 알아보자.

GeometryReader는 쉽게 말해서 디바이스 기기마다 대응하기 위함이다.

음,, 대충 오토 레이아웃이라고 생각하면 좋아!

 

✅ 코드

import SwiftUI

enum Index { // enum으로 처리한다.
    case one, two, three
}

struct MyGeometryReaderVStack : View {
    
    @State var index: Index = .one // 초기 상태는 one으로
    
    var body: some View{
        
        // 부모뷰의 비율을 사용 가능하다.
        GeometryReader{ geometry in 
            VStack{
                
                Button(action:{
                    // 버튼이 클릭되었을때 로직
                    print("1번이 클릭되었습니다.")
                    
                    withAnimation { // 애니메이션을 걸기 위함.
                        self.index = .one // index를 1로 바꾼다. 
                    }
                    
                }){
                    // 버튼의 생김새
                    Text("1")
                    .font(.largeTitle)
                    .fontWeight(.black)
                    .frame(width: 100, height: geometry.size.height / 3)
                    .padding(.horizontal, self.index == .one ? 50 : 0)
                    .foregroundColor(Color.white)
                    .background(Color.red)
                }
                
                Button(action:{
                    // 버튼이 클릭되었을때 로직
                    print("2번이 클릭되었습니다.")
                    
                    withAnimation {
                        self.index = .two
                    }
                    
                    
                }){
                    // 버튼의 생김새
                    Text("2")
                    .font(.largeTitle)
                    .fontWeight(.black)
                    .frame(width: 100, height: geometry.size.height / 3)
                    .padding(.horizontal, self.index == .two ? 50 : 0)
                    .foregroundColor(Color.white)
                    .background(Color.blue)
                }
                
                Button(action:{
                    // 버튼이 클릭되었을때 로직
                    print("3번이 클릭되었습니다.")
                    
                     withAnimation {
                       self.index = .three
                    }
                    
                }){
                    // 버튼의 생김새
                    Text("3")
                    .font(.largeTitle)
                    .fontWeight(.black)
                    .frame(width: 100, height: geometry.size.height / 3)
                    .padding(.horizontal, self.index == .three ? 50 : 0)
                    .foregroundColor(Color.white)
                    .background(Color.green)
                }
            }
        }
        .background(Color.yellow)
        .edgesIgnoringSafeArea(.all)
        

    }
}

이렇게 바뀌는데 애니메이션이 적용된다.

 

 

SwiftUI에서 코드 접는 펴는 방법 

 - 알트 커멘트 왼쪽(오른쪽)

 

✅ GeometryProxy position

이건 왜 사용하냐면 절대적인 포지션을 잡기 위함이다.

GeometryReader"뷰의 좌표에 이름을 정해서 다른 코드에서 작동하도록 하는 메서드"

GeometryProxy는 "컨테이너 뷰의 좌표나 크기를 접근할 수 있는 것"

 

즉, GeometryReader는 기하학적인 정보를 가지고 있는 컨테이너 뷰 자체이고 해당 정보를 얻어내기 위해선 GeometrryProxy를 이용해야 하는 것이죠.

import SwiftUI

enum Index {
    case one, two, three
}

struct MyGeometryReaderVStack : View {
    
    @State var index : Index = .one
    
    // 지오메트리 프록시를 매개변수로 가지고 CGPoint 를 반환하는 클로져
    let centerPosition : (GeometryProxy) -> CGPoint = { proxy in
        return CGPoint(x: proxy.frame(in: .local).midX,
                       y: proxy.frame(in: .local).midY)
    }
    
    var body: some View {
        
        GeometryReader { proxy in
            
            VStack {
                Button(action: {
                    // 버튼이 클릭되었을때 로직
                    print("1번이 클릭되었습니다.")
                    
                    withAnimation {
                        self.index = .one
                    }
                    
                }){
                    // 버튼의 생김새
                    Text("1")
                    .font(.largeTitle)
                    .fontWeight(.black)
                    .frame(width: 100, height: proxy.size.height / 3)
                    .padding(.horizontal, self.index == .one ? 50 : 0)
                    .foregroundColor(Color.white)
                    .background(Color.red)
                }
                
//                Button(action: {
//                    // 버튼이 클릭되었을때 로직
//                    print("2번이 클릭되었습니다.")
//
//                    withAnimation {
//                        self.index = .two
//                    }
//
//
//                }) {
//                    // 버튼의 생김새
//                    Text("2")
//                    .font(.largeTitle)
//                    .fontWeight(.black)
//                    .frame(width: 100, height: proxy.size.height / 3)
//                    .padding(.horizontal, self.index == .two ? 50 : 0)
//                    .foregroundColor(Color.white)
//                    .background(Color.blue)
//                }
//
//                Button(action: {
//                    // 버튼이 클릭되었을때 로직
//                    print("3번이 클릭되었습니다.")
//
//                     withAnimation{
//                       self.index = .three
//                    }
//
//                }) {
//                    // 버튼의 생김새
//                    Text("3")
//                    .font(.largeTitle)
//                    .fontWeight(.black)
//                    .frame(width: 100, height: proxy.size.height / 3)
//                    .padding(.horizontal, self.index == .three ? 50 : 0)
//                    .foregroundColor(Color.white)
//                    .background(Color.green)
//                }
            }
//            .position(CGPoint(x: proxy.frame(in: .local).midX, y: proxy.frame(in: .local).midY))
            .position(centerPosition(proxy))
            
        }
        .background(Color.yellow)
        .edgesIgnoringSafeArea(.all)
        

    }
}

 

프록시로 세팅

 

 

(참고)

https://fomaios.tistory.com/entry/SwiftUI-GeometryReader%EB%9E%80?category=933741 

 

[SwiftUI] GeometryReader란? (feat. GeometryProxy,CoordinateSpace)

안녕하세요 Foma 💻 입니다! 오늘은 SwitUI를 이용해서 Layout을 잡을 때 아주 유용하게 사용되는 GeometryReader에 대해서 알아보려고 합니다. 바로 시작할게요~ GeometryReader란? 이름을 직역하면 Geometry는

fomaios.tistory.com