I need to generate an image from a custom view composed by an UIImageView
and an UILabel
.
I can't use the new iOS 7 drawViewHierarchyInRect:afterScreenUpdates:
because I have some ugly glitch on iPhone 6/6+ (iOS8 scale glitch when calling drawViewHierarchyInRect afterScreenUpdates:YES)
So I did it the old fashion way using renderInContext:
which works well but it's quite slow. I'm using image generation to display markers in a GMSMapView
(god I missed MapKit
...) but the user experience is quite bad because of lags due to those image generation.
So I try to perform the image creation operation in a background thread in order to have something smooth but here's the problem : the majority of my labels are not rendered.
Anyone as already faced this issue ?
Here's the code I used :
func CGContextCreate(size: CGSize) -> CGContext {
let scale = UIScreen.mainScreen().scale
let space: CGColorSpaceRef = CGColorSpaceCreateDeviceRGB()
let bitmapInfo: CGBitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedFirst.rawValue)
let context: CGContext = CGBitmapContextCreate(nil, Int(size.width * scale), Int(size.height * scale), 8, Int(size.width * scale * 4), space, bitmapInfo)
CGContextScaleCTM(context, scale, scale)
CGContextTranslateCTM(context, 0, size.height)
CGContextScaleCTM(context, 1, -1)
return context
}
func UIGraphicsGetImageFromContext(context: CGContext) -> UIImage? {
let cgImage: CGImage = CGBitmapContextCreateImage(context)
let image = UIImage(CGImage: cgImage, scale: UIScreen.mainScreen().scale, orientation: UIImageOrientation.Up)
return image
}
extension UIView {
func snapshot() -> UIImage {
let context = CGContextCreate(self.frame.size)
self.layer.renderInContext(context)
let image = UIGraphicsGetImageFromContext(context)
return image!
}
func snapshot(#completion: UIImage? -> Void) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let image = self.snapshot()
completion(image)
}
}
}