iosswiftuikitmac-catalyst

drawHierarchy broken - image too bright


EDIT1

I have created github repo to reproduce the issue

https://github.com/PrashantKT/ImageViewScreenShotIssue

it is just 2 page app to demonstrate the problem

I have this code to take screenshot of view:

extension UIView {
    func takeSnapshot(rect : CGRect? = CGRect.zero) -> UIImage? {
        let renderer = UIGraphicsImageRenderer(size: frame.size)
        var image = renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) }
        if let imageRect = rect, imageRect != CGRect.zero {
            let screenshotFrame = CGRect(x: imageRect.origin.x * UIScreen.main.scale, y: imageRect.origin.y * UIScreen.main.scale, width: imageRect.size.width * UIScreen.main.scale, height: imageRect.size.height * UIScreen.main.scale)
            let imageRef = image.cgImage!.cropping(to: screenshotFrame)
            image = UIImage.init(cgImage: imageRef!, scale: image.scale, orientation: image.imageOrientation)
        }
        UIGraphicsEndImageContext()
        return image
    }
    
}

which was working fine until I updated to macOS 14.4.1 from 14.2.1 and to Xcode 15.3 from 15.0.

issue

From my Mac Catalyst app, if I try to take screenshot of imageView, the screenshot is brighter.

Using this method

2)

If I try this method:

func takeSnapshotWithoutScale()  -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0)
    if let currentContext = UIGraphicsGetCurrentContext() {
        self.layer.render(in: currentContext)
    }
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

Method 2


Solution

  • Prashant Tukadiya. Replace this category (in your github example):

    extension UIView {
      func takeSnapshot() -> UIImage? {
        let renderer = UIGraphicsImageRenderer(size: frame.size)
        let image = renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) }
        
        UIGraphicsEndImageContext()
        return image
      }
    }
    

    with this one:

    extension UIView {
      func takeSnapshot() -> UIImage? {
        let format = UIGraphicsImageRendererFormat()
        format.preferredRange = .standard
        let renderer = UIGraphicsImageRenderer(size: frame.size, format: format)
        let image = renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) }
        
        UIGraphicsEndImageContext()
        return image
      }
    }