티스토리 뷰

가이드

SwiftUI에서 뷰 스크린샷 캡쳐하기

Sunghyun Kim 2022. 7. 30. 16:37

UIView의 경우 익히 알려진 방법들로 스크린샷을 촬영할 수 있다.

extension UIView {
    func snapshot() -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: bounds.size)
        return renderer.image { context in
            drawHierarchy(in: bounds, afterScreenUpdates: true)
        }
    }
}

SwiftUI의 View 타입은 UIView와 다르게 업데이트 시마다 이니셜라이즈된다. 뷰의 렌더된 이미지나 속성을 가지지 않고 UIView를 업데이트해주는 빌더라고 할 수 있다. 그래서 스크린샷 등 렌더링된 이미지를 구하려면 UIKit의 도움을 받아야 한다.

View 타입을 즉시 렌더링하여 저장하기

extension View {
    func snapshot() -> UIImage? {
        // 1
        let hostingController = UIHostingController(rootView: self.ignoresSafeArea())
        guard let view = hostingController.view else { return nil }
        // 2
        let targetSize = view.intrinsicContentSize
        view.bounds = CGRect(origin: .zero, size: targetSize)
        view.backgroundColor = .clear
        // 3
        let rederer = UIGraphicsImageRenderer(size: targetSize)
        return rederer.image { context in
            view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
        }
    }
}
  1. UIHostingController를 사용해 View 타입을 UIViewController로 변환하고 view를 가져온다.
  2. 뷰가 그려질 사이즈인 intrinsicContentSize에 접근해 사이즈를 가져온다.
  3. 뷰를 크기에 맞게 렌더링하고 이미지를 가져온다.
struct ContentView: View {
    private var viewForSnapshot: some View {
        Text("스크린샷 찍을 뷰")
    }

    var body: some View {
        VStack {
            viewForSnapshot
            Button("촬영") {
                text.snapshot()
            }
        }
    }
}

이 방법을 사용하면 상위 뷰에서 하위 뷰를 프로퍼티로 저장해놓고 snapshot()을 호출하여 스크린샷을 촬영할 수 있다. 그러나 스스로 크기가 정해지는 뷰(예: 텍스트 등)가 아니면 제대로 작동하지 않는다.

상위 뷰에 의해 크기가 결정되는 뷰의 경우는 실제 렌더링된 UIView 객체를 참조해야 스크린샷을 찍을 수 있다.

Introspect로 UIViewController 가져오기

Introspect라는 오픈소스 라이브러리를 이용하면 손쉽게 기존 UIKit 뷰를 가져와 사용할 수 있다.

Text("스크린샷 찍을 뷰")
.introspectViewController { viewController in
    viewForSnapshot = viewController.view
}

UIView를 가져와 저장했다면 UIView의 스크린샷 촬영 메소드를 호출해 촬영을 하면 된다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함