WKWebView 스크린샷

개발/iOS 2020. 5. 12. 15:34
반응형

WKWebView에서 화면 스크롤영역 전체 스크린샷을 구하는 방법을 알아보겠습니다.

iOS 11버전 부터 takeSnapshot이라는 함수를 제공하지만 실제로 정상적인 결과를 얻을 수 없습니다.

아래 클래스를 이용하면 보여지지 않는 스크롤 영역 전체의 스크린 샷을 구해 고화질로 저장할 수 있습니다.

주의 : 해당 함수는 웹페이지 로딩이 완료된 뒤 호출하셔야 합니다.

extension WKWebView{
    // 화면에 보여지는 부분만 스크린샷
    func screenshot(_ completionBlock: ((UIImage) -> Void)?) {
        if #available(iOS 11.0, *) {
            let config = WKSnapshotConfiguration()
            if #available(iOS 13.0, *) {
                config.afterScreenUpdates = false
            }
            config.rect = self.frame
            // iOS 11.0부터 takeSnapshot 함수를 사용할 수 있으나 스크롤영역 전체 스크린샷은 지원하지 않음(시뮬레이터는 가능)
            self.takeSnapshot(with: config, completionHandler: { image, error in
                if error != nil {
                    print("\(String(describing: error))")
                    return
                }
                guard let image = image else { return }
                completionBlock?(image)
            })
        } else {
            UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, UIScreen.main.scale);
            self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
            guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }
            UIGraphicsEndImageContext();
            completionBlock?(image)
        }
    }
    
    // 현재 페이지의 모든 컨텐츠 스크린샷
    func screenshot2(_ completionBlock: ((UIImage) -> Void)?) {
        let sv = self.scrollView
        let offset = sv.contentOffset
        let pageSize = sv.contentSize;
        let maxWidth = CGFloat(ceil(pageSize.width/sv.frame.size.width))
        let maxHeight = CGFloat(ceil(pageSize.height/sv.frame.size.height))
        for x in stride(from: 0, to: maxHeight, by: 1.0) {
            for y in stride(from: 0, to: maxWidth, by: 1.0) {
                sv.scrollRectToVisible(CGRect(x: sv.frame.size.width  * x,
                                              y: sv.frame.size.height * y,
                                              width:  sv.frame.size.width,
                                              height: sv.frame.size.height), animated: true)
                RunLoop.main.run(until: Date.init(timeIntervalSinceNow: 1.0))
            }
        }
        sv.setContentOffset(offset, animated: false)
        
        let prevOffset = sv.contentOffset
        let prevBounds = self.bounds
        let prevFrame = self.frame
        
        UIGraphicsBeginImageContext(pageSize)
        self.bounds = CGRect(x: self.bounds.origin.x, y: self.bounds.origin.y, width: pageSize.width, height: pageSize.height)
        self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: pageSize.width, height: pageSize.height)
        RunLoop.main.run(until: Date.init(timeIntervalSinceNow: 0.5))
        self.layer.render(in: UIGraphicsGetCurrentContext()!)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        self.bounds = prevBounds
        self.frame = prevFrame
        sv.setContentOffset(prevOffset, animated: false)
        completionBlock?(image)
    }
}

 

☞ 웹뷰 화면 보여지는 부분만 스크린샷

webView.screenshot({(image) in
    print("complete")
})

 

☞ 웹뷰 화면 전체 스크린샷 (스크롤영역 전체)

webView.screenshot2({(image) in
    print("complete")
})

 

2020/05/12 - [iOS/Swift] - WKWebView 스크린샷

2020/05/12 - [iOS/Swift] - json 포멧 체크

2020/05/12 - [iOS/Swift] - Access Control (접근 제한자)

2020/05/12 - [iOS/Swift] - WKWebview에서 tel, email, mailto, sms, facetime 처리

 

반응형

'개발 > iOS' 카테고리의 다른 글

iOS디바이스 설정창 이동  (0) 2020.05.15
Xcode 한글 깨짐 복구  (0) 2020.05.15
json 포멧 체크  (0) 2020.05.12
Access Control (접근 제한자)  (0) 2020.05.12
WKWebview에서 tel, email, mailto, sms, facetime 처리  (0) 2020.05.12
블로그 이미지

SKY STORY

,