반응형
네이티브 UIScrollView 화면에서 스크린샷 구하는 방법에 대해 알아보자.
일반적으로 스크린샷을 구해보면 화면에 보이는 부분만
구해지며 숨겨진 영역은 흰색화면으로 출력된다. (iOS 13.0이상 에서 생기는 버그)
extension UIScrollView {
func screenshot() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(contentSize, false, 0.0)
let savedContentOffset = contentOffset
let savedFrame = frame
defer {
UIGraphicsEndImageContext()
contentOffset = savedContentOffset
frame = savedFrame
}
contentOffset = .zero
frame = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height)
guard let ctx = UIGraphicsGetCurrentContext() else {
return nil
}
layer.render(in: ctx)
let image = UIGraphicsGetImageFromCurrentImageContext()
return image
}
}
이를 위해 UIScrollView를 부모로 부터 Layout 컨텐츠를 비활성하고 스크린샷 이미지를 구하고 다시
원래대로 활성화 시켜주는 방법으로 해결 가능하다.
extension UIScrollView {
func screenshot() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(contentSize, false, 0.0)
let savedContentOffset = contentOffset
let actualConstraints = relatedConstraints()
NSLayoutConstraint.deactivate(actualConstraints)
translatesAutoresizingMaskIntoConstraints = true
frame = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height)
contentOffset = .zero
defer {
UIGraphicsEndImageContext()
translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate(actualConstraints)
superview?.layoutIfNeeded()
contentOffset = savedContentOffset
}
guard let ctx = UIGraphicsGetCurrentContext() else {
return nil
}
layer.render(in: ctx)
let image = UIGraphicsGetImageFromCurrentImageContext()
return image
}
}
extension UIView {
func relatedConstraints() -> [NSLayoutConstraint] {
var constraints = self.constraints
var parent = superview
while parent != nil {
constraints.append(contentsOf: parent!.constraints.filter { $0.firstItem === self || $0.secondItem === self })
parent = parent!.superview
}
return constraints
}
class func getAllSubviews<T: UIView>(from parenView: UIView) -> [T] {
return parenView.subviews.flatMap { subView -> [T] in
var result = getAllSubviews(from: subView) as [T]
if let view = subView as? T { result.append(view) }
return result
}
}
class func getAllSubviews(from parenView: UIView, types: [UIView.Type]) -> [UIView] {
return parenView.subviews.flatMap { subView -> [UIView] in
var result = getAllSubviews(from: subView) as [UIView]
for type in types {
if subView.classForCoder == type {
result.append(subView)
return result
}
}
return result
}
}
func getAllSubviews<T: UIView>() -> [T] { return UIView.getAllSubviews(from: self) as [T] }
func get<T: UIView>(all type: T.Type) -> [T] { return UIView.getAllSubviews(from: self) as [T] }
func get(all types: [UIView.Type]) -> [UIView] { return UIView.getAllSubviews(from: self, types: types) }
}
/*
// 현재 뷰의 하위뷰 중 UIScrollView를 구한다.
if let scrollView = self.view.get(all: UIScrollView.self).first {
// 스크롤뷰의 모든 컨텐츠가 나오도록 스크린샷 이미지로 반환한다.
let image = scrollView.screenshot()
// 주어진 이미지를 공유
DispatchQueue.main.async {
let imageToShare = [ image ]
let activityVC = UIActivityViewController(activityItems: imageToShare as [Any], applicationActivities: nil)
self.present(activityVC, animated: true, completion: nil)
}
}
*/
반응형
'개발 > iOS' 카테고리의 다른 글
Carthage 설치 및 제거 (0) | 2023.01.11 |
---|---|
NSURLSessionTask 캐싱 비활성화 (0) | 2022.10.24 |
문자열 숫자에 콤마 넣기 (0) | 2022.10.14 |
유니버셜 링크(Universal Links) 문제점 해결 (0) | 2022.07.21 |
웹 저장 데이터 (Cookie, Cache) 삭제 (0) | 2021.09.24 |