4

I am using Swift 5 and iOS 13. I am trying to take a screenshot of the entire scrollview image and print it, but the bottom appears in white. How can i solve this problem? I showed and explained everything in the picture below.

I am also checked this topic

enter image description here

My extension code like this:

extension UIScrollView {

    func screenshot() -> UIImage {

        let savedContentOffset = contentOffset
        let savedFrame = frame

        UIGraphicsBeginImageContextWithOptions(contentSize, false, 0)

        contentOffset = .zero
        frame = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        contentOffset = savedContentOffset
        frame = savedFrame

        return image ?? UIImage()

    }

}
Hilalkah
  • 945
  • 15
  • 37
  • Check the topic again that you linked - it has answers how to fix the issue for iOS 13 - cloning scroll view with keyed archiver or removing it from parent. Why it happens - I believe due to autolayout and existing constraints. – Mikhail Mar 20 '20 at 14:08
  • Are you using a table view or collection view? Both of them are subclass of scroll view. And both of them are designed to not draw content that is not visible on the screen. – Matic Oblak Mar 20 '20 at 14:09
  • @MaticOblak Yes, I have collectionView in my scrollView. – Hilalkah Mar 20 '20 at 14:20
  • @Mikhail I look it and can't find answer in Swift. Can you write the solution? – Hilalkah Mar 20 '20 at 14:21

2 Answers2

4

Here is the code snippet that worked for me.

extension UIView {
    
    func snapshot(scrollView: UIScrollView) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, false, UIScreen.main.scale)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let savedContentOffset = scrollView.contentOffset
        let savedFrame = frame
        
        scrollView.contentOffset = CGPoint.zero
        frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height)
        
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        
        scrollView.contentOffset = savedContentOffset
        frame = savedFrame
        
        UIGraphicsEndImageContext()
        
        return image
    }
}

And when you call it:

view.snapshot(scrollView: scrollView)
Sami Ali
  • 163
  • 3
  • 10
2

It's seems like iOS 13 bug but I found the solution in this answer.

The solution is I am removing scrollview from superview and then adding in with its old constraints after taking the screenshot. Yeah, it's stupid but it just works that way :(

scrollView.removeFromSuperview()
let print = scrollView.screenshot()
mainView.addSubview(scrollView)
scrollView.snp.makeConstraints { (make) in
    make.top.equalTo(topView.snp.bottom)
    make.left.bottom.right.equalToSuperview()
}
Hilalkah
  • 945
  • 15
  • 37