Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
SwiftUI/SwiftUI(Intermediate)

13. GeometryReader / rotation3DEffect

by Toughie 2023. 5. 25.

⭐️GeometryReader / rotation3DEffect ⭐️

 

GeometryReader는 내부 뷰들의 크기와 위치에 대한 정보를 얻기 위해 사용하는 컨테이너뷰이다.

여러 상황에서 유용할 수 있지만 단점이 있기 때문에 최대한 사용을 지양하는 편도 좋다.

 

GeometryReader는 뷰 계층 구조를 재계산하고 측정하기 때문에 많은 연산 능력을 요구한다.(컴퓨팅 파워)

즉 자식 뷰의 크기와 위치에따라 크기 조정을 수행하는데, 자식 뷰의 크기가 변경될 때마다 다시 계산된다는 말이다.

이러면 레이아웃 계산이 많아져서 성능 저하가 발생할 수 있다. 

 

1. GeometryReader 사용을 최소화 하기.(꼭 필요한 경우만!), 그리고 중첩 사용 피하기

2. GeometryReder 내에서 복잡한 작업 수행 지양

3. 큰 크기의 GeometryReader 사용 지양

 

위 요소들을 고려하면 GeometryReader 사용으로 인한 성능저하를 방지할 수 있을 것이다.

 

하지만 다이나믹한 화면 구성을 위해서는 사용해야되는 경우도 있는데,

rotation3DEffect와 함께 다음과 같은 뷰를 구현해보자.

//  Created by Toughie on 2023/05/25.
//

import SwiftUI

struct GeometryReaderPrac: View {
    var body: some View {
        
        ZStack {
            Color.yellow.opacity(0.2).ignoresSafeArea()
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    ForEach(0..<20) { index in
                    
                        GeometryReader { geo in
                            Image("이미지")
                                .resizable()
                                .scaledToFit()
                                //앵글에 따라 3가지 축(X, Y, Z)으로 뷰 렌더링을 회전하는 이펙트
                                .rotation3DEffect(Angle(degrees: getPercentage(geo: geo) * 30),
                                                  axis: (x: 0.5, y: 1, z: 0.5))
                        }
                        .frame(width: 300, height: 400)
                        .padding()
                    }
                }
                .padding(.top, 100)
            }
        }
    }
    
    func getPercentage(geo: GeometryProxy) -> Double {
        let maxDistance = UIScreen.main.bounds.width / 2
        //위 예시에서 사진의 정 중앙 위치를 계산
        let currentX = geo.frame(in: .global).midX
        return Double(1 - (currentX / maxDistance))
    }
}