【问题标题】:UIGraphicsImageRenderer generates a strange top padding on iOS 15, working fine on iOS 14.xUIGraphicsImageRenderer 在 iOS 15 上生成一个奇怪的顶部填充,在 iOS 14.x 上工作正常
【发布时间】:2021-11-05 23:57:34
【问题描述】:

当我使用 UIGraphicsImageRenderer 将 SwiftUI 视图导出到图像时,iOS 15 会生成一个奇怪的顶部填充。它在 iOS 14.x 上运行良好。有人知道为什么吗?

【问题讨论】:

  • 您展示了 2 张不同的图像,请尝试在两个版本中使用相同的图像显示问题。 PS:我认为问题在于您的代码中的其他内容,并显示您使用该功能的视图。
  • 您是否检查过intrinsicContentSize 是否符合您对图像大小的预期。许多视图并没有真正的内在大小,所以如果这是一个问题,我不会感到惊讶。

标签: ios swift swiftui core-graphics


【解决方案1】:

事实证明这是 iOS 15 的真正问题。

我在 Twitter 上发布了同样的问题,并得到了一个有效的解决方案。

你可以阅读更多关于这个问题here

解决办法在这个gist

为了完整起见,我在这里发布了要点,但所有功劳归其作者(不是我):

//
//  View+Snapshot.swift
//
//  Created by Vinzius on 2021-11-06.
//

import SwiftUI
import UIKit.UIImage
import UIKit.UIGraphicsImageRenderer

extension View {
    
    func snapshot() -> UIImage? {
        
        // Note: since iOS 15 it seems these two modifiers are required.
        let controller = UIHostingController(
            rootView: self.ignoresSafeArea()
                .fixedSize(horizontal: true, vertical: true)
        )
        guard let view = controller.view else { return nil }
        
        let targetSize = view.intrinsicContentSize
        if targetSize.width <= 0 || targetSize.height <= 0 { return nil }
        
        view.bounds = CGRect(origin: .zero, size: targetSize)
        view.backgroundColor = .clear

        let renderer = UIGraphicsImageRenderer(size: targetSize)
        
        return renderer.image { _ in
            view.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
        }
        
    }
    
}

【讨论】: