Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

ios - Exclude View from Screenshot

This is how I take a screenshot of my view:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0)
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

However, in the view, there is a UIVisualEffectsView which I'd like to exclude from the screenshot.
I tried hiding the UIVisualEffectsView just before taking the screenshot and un-hiding it afterwards but I don't want the user to see that process. (which he does if I simply hide the view because the iPad is too slow and it looks like the screen is flickering...)

Any ideas? Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would take advantage of the snapshotViewAfterScreenUpdates() method

This method very efficiently captures the current rendered appearance of a view and uses it to build a new snapshot view. You can use the returned view as a visual stand-in for the current view in your app.

Therefore you can use it in order to display an overlay UIView of the complete un-altered view hierarchy to the user while rendering a version of the hierarchy with your changes underneath it.

The only caveat is that if you're capturing a view controller's hierarchy, you'll have to create a 'content view' subview in order to prevent the overlay view from being rendered in your screenshot where you make the changes to the hierarchy. You'll then want to add your view hierarchy that you want to render to this 'content view'.

So your view hierarchy will want to look something like this:

UIView // <- Your view
    overlayView // <- Only present when a screenshot is being taken
    contentView // <- The view that gets rendered in the screenshot
        view(s)ToHide // <- The view(s) that get hidden during the screenshot

Although, if you are able to add the overlayView to the view's superview - instead of to the view itself – you don't need to mess about with the hierarchy at all. For example:

overlayView // <- Only present when a screenshot is being taken
UIView // <- Your view – You can render this in the screenshot
    view(s)ToHide // <- The view(s) that get hidden during the screenshot
    otherViews // <- The rest of your hierarchy

Something like this should achieve the desired result:

// get a snapshot view of your content
let overlayView = contentView.snapshotViewAfterScreenUpdates(true)

// add it over your view
view.addSubview(overlayView)

// do changes to the view heirarchy
viewToHide.hidden = true

// begin image context
UIGraphicsBeginImageContextWithOptions(contentView.frame.size, false, 0.0)

// render heirarchy
contentView.drawViewHierarchyInRect(contentView.bounds, afterScreenUpdates: true)

// get image and end context
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

// reverse changes to the view heirarchy
viewToHide.hidden = false

// remove the overlay view
overlayView.removeFromSuperview()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...