fmas
fmas

Reputation: 13

Content of scrollview clear when taking screenshot

I have a scrollview and i need a screenshot of the complete content of that scrollview, i search and try many solutions on stackoverflow but that provide only the screenshot of the total height of the viewcontroller. For example if the height of the scrollview is 1096 and Viewcontroller height is 532 , it screenshot the content according to the Viewcontroller height I found only this code useful on stackoverflow and it return the complete height of the scrollview but it clear the content of scrollview in the Viewcontroller. Any help how to retain the content of scrollview or any better solution to take a complete screenshot in swift. Thankyou

func getImageOfScrollView()->UIImage{
    var image = UIImage();

    UIGraphicsBeginImageContextWithOptions(self.scrollView.contentSize, false, UIScreen.mainScreen().scale)

    // save initial values
    let savedContentOffset = self.scrollView.contentOffset;
    let savedFrame = self.scrollView.frame;
    let savedBackgroundColor = self.scrollView.backgroundColor

    // reset offset to top left point
    self.scrollView.contentOffset = CGPointZero;
    // set frame to content size
    self.scrollView.frame = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height);
    // remove background
    self.scrollView.backgroundColor = UIColor.clearColor()

    // make temp view with scroll view content size
    // a workaround for issue when image on ipad was drawn incorrectly
    let tempView = UIView(frame: CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height))

    // save superview
    let tempSuperView = self.scrollView.superview
    // remove scrollView from old superview
    self.scrollView.removeFromSuperview()
    // and add to tempView
    tempView.addSubview(self.scrollView)

    // render view
    // drawViewHierarchyInRect not working correctly
    tempView.layer.renderInContext(UIGraphicsGetCurrentContext())
    // and get image
    image = UIGraphicsGetImageFromCurrentImageContext();

    // and return everything back
    tempView.subviews[0].removeFromSuperview()
    tempSuperView?.addSubview(self.scrollView)

    // restore saved settings
    self.scrollView.contentOffset = savedContentOffset;
    self.scrollView.frame = savedFrame;
    self.scrollView.backgroundColor = savedBackgroundColor

    UIGraphicsEndImageContext();

    return image
}

Upvotes: 0

Views: 740

Answers (1)

beyowulf
beyowulf

Reputation: 15321

Using this as I guide, I think you can snapshot any view using:

func snapShot(view:UIView) -> UIImage
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, true, 0)
    view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}

Though with a scroll view this will only return an image of what's visible in the scroll view's frame, so we can create a helper function:

func snapShotScrollView(scrollView:UIScrollView) -> UIImage
{
    let bounds = scrollView.bounds
    scrollView.bounds.size = scrollView.contentSize
    let image = snapShot(scrollView)
    scrollView.bounds = bounds
    return image
}

This will briefly adjust our scroll view's bounds to it's content size.

I don't know how performant this code is, but this works for me in a swift playground. For example, running this code:

let scrollView = UIScrollView(frame:CGRect(x: 0.0, y: 0.0, width: 200.0, height: 200.0))
scrollView.backgroundColor = UIColor.whiteColor()
scrollView.contentSize = CGSize(width: 600.0, height: 600.0)
let blueView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 200.0))
blueView.backgroundColor = UIColor.blueColor()

let redView = UIView(frame: CGRect(x: 200.0, y: 200.0, width: 400.0, height: 600.0))
redView.backgroundColor = UIColor.redColor()
scrollView.addSubview(blueView)
scrollView.addSubview(redView)
let image = snapShotScrollView(scrollView)

Results in enter image description here where as calling snapShot by itself only returns a blue square. After the snapshot the scroll view is the original size with the original content.

Upvotes: 1

Related Questions