Getting a screenshot of a UIScrollView, including offscreen parts

前端 未结 12 2223
遥遥无期
遥遥无期 2020-11-22 17:31

I have a UIScrollView decendent that implements a takeScreenshot method that looks like this:

-(void)takeScreenshot {  
  CGRect contextRect  =          


        
12条回答
  •  爱一瞬间的悲伤
    2020-11-22 17:59

    For me, the currently accepted answer from Stefan Arentz didn't work.

    I had to implement this on iOS 8 and above, and tested on the iPhone. The accepted answer just renders the visible part of a scroll view, while the rest of image remains blank.

    I tried fixing this using drawViewHierarchyInRect - no luck. Depending on afterScreenUpdates being true or false I got stretched part of image or only part of the contents.

    The only way I've found to achieve correct snapshotting of a UIScrollView's entire contents is to add it to another temporary view and then render it.

    Sample code is below (scrollview is outlet in my VC)

    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
    }
    

提交回复
热议问题