SwiftUI

[SwiftUI] GeometryReader로 반응형 화면 만들기

쵱니 2025. 5. 10. 01:23

여기서 [미리 보기] 의 스크린 샷 처럼 스크린 샷 하나가 전체 화면의 일부분만 차지하게 만들고 싶었다.

-> GeometryReader를 overlay해서 해결

import SwiftUI

struct AppScreenShotView: View {
    @State var imageWidth: CGFloat = 300
    let horizontalPadding: CGFloat = 21

    var body: some View {
        VStack(spacing: 12) {
            HStack {
                Text("미리 보기")
                    .font(19, .bold)
                Spacer()
            }
            .padding(.horizontal, 21)

            ScrollView(.horizontal) {
                HStack {
                    ForEach(0..<4) {
                        Image("kakaoBankScreenShot\($0)")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: imageWidth)
                    }
                }
                .padding(.horizontal, horizontalPadding)
                .scrollTargetLayout()
            }
            .scrollIndicators(.never)
            .scrollTargetBehavior(.viewAligned)
            .overlay {
                GeometryReader() { geometry -> Color in
                    let totalWidth = geometry.size.width
                    let availableWidth = totalWidth - (self.horizontalPadding * 2)
                    Task { @MainActor in
                        self.imageWidth = availableWidth * (2 / 3)
                    }
                    return Color.clear
                }
            }
        }
    }
}
  1. .overlay를 통해서 해당 View 의 width 계산
  2. 해당 View를 계산한 것을 @State 선언되어 있는 imageView를 전달.
  3. 이 때 반드시 Main Thread에 작동하도록 해야 한다.

엥? 그냥 GeometryReader로 감싸면 안됨?

응 안됨.

Geometry 화면으로 감싸면 automaticSize가 깨지는 듯하다.

즉. Image의 height가 엄청 낮게 설정되어서 안된다.