Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take a screenshot of UIView on a background thread?

The app I'm working on has google maps on almost every screen. To save memory, I'm reusing the same google maps view everywhere. The problem is, when you pop a viewController, you can see a white space where the map was. To work around that I'm taking screenshots of it and adding as a background before removing the map. But there's another problem, taking a screenshot takes about 0.3 seconds on iPhoneX (I suppose it's even worse on older phones). Is there any way to take screenshots of UIView on a background thread?

like image 293
Senõr Ganso Avatar asked Dec 10 '25 17:12

Senõr Ganso


2 Answers

I tried all the latest snapshot methods using swift. Other methods didn't work for me in the background. But taking snapshot this way worked for me.

create an extension with parameters view layer and view bounds.

extension UIView {
    func asImageBackground(viewLayer: CALayer, viewBounds: CGRect) -> UIImage {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(bounds: viewBounds)
            return renderer.image { rendererContext in
                viewLayer.render(in: rendererContext.cgContext)
            }
        } else {
            UIGraphicsBeginImageContext(viewBounds.size)
            viewLayer.render(in:UIGraphicsGetCurrentContext()!)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return UIImage(cgImage: image!.cgImage!)
        }
    }
}

Usage

DispatchQueue.main.async {
                let layer = self.selectedView.layer
                let bounds = self.selectedView.bounds
                DispatchQueue.global(qos: .background).async {
                    let image = self.selectedView.asImageBackground(viewLayer: layer, viewBounds: bounds)
                }
            }

We need to calculate layer and bounds in the main thread, then other operations will work in the background thread. It will give smooth user experience without any lag or interruption in UI.

like image 143
Faris Muhammed Avatar answered Dec 12 '25 07:12

Faris Muhammed


Actually ,it is possible! But first on UIThread you need get some infos Like this:

CALayer* layer = view.layer;
CGRect frame = view.frame;

, then change to backgroundthead use codes below to get image:

UIGraphicsBeginImageContextWithOptions(frame.size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
like image 45
Hongwei Lv Avatar answered Dec 12 '25 07:12

Hongwei Lv



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!