SwiftUI - 如何将 macOS 的 NSImage 转换为 iOS 的 UIImage

SwiftUI - How to translate NSImage for macOS to UIImage for iOS

我正在学习本教程以了解如何使用 SwiftUI 进行拖放操作。 https://swiftui-lab.com/drag-drop-with-swiftui/

这是我第一次从 URL 获取图像,教程中的代码使用 macOS 的 NSImages,但是,我需要为 iOS 构建,因此,NSImage 必须改为 UIImage.

我能够在 DragableImage 结构中将 NSImage 转换为 UIImage,但是,我在处理 GridCell 结构图像时遇到了问题。特别是将 URL 展开到 img 变量中并将其作为矩形顶部的覆盖层返回。请参阅下面的代码。

struct GridCell: View {
            let active: Bool
            let url: URL?
            
            var body: some View {
            // translate NSImage to UIImage here
                let img = Image(nsImage: url != nil ? NSImage(byReferencing: url!) : NSImage()) 
                    .resizable()
                    .frame(width: 150, height: 150)
                
                return Rectangle()
                    .fill(self.active ? Color.green : Color.clear)
                    .frame(width: 150, height: 150)
                    .overlay(img)
            }
        }

非常感谢任何将 NSImage 转换为 UIImage 的帮助。

如果您使用 iOS 15 - 请改用 AsyncImage 从 URL.

加载
let img = AsyncImage(url: url)

此处的文档:https://developer.apple.com/documentation/swiftui/asyncimage


如果您需要支持 iOS 14 或更低版本,从 URL 创建 UIImage 的一种方法是定义扩展:

extension UIImage {
  static func fromUrl(url: URL?) -> UIImage {
    if let url = url,
      let data = try? Data(contentsOf: url),
      let image = UIImage(data: data) {
      return image
    } else {
      return UIImage()
    }
  }
}

然后将其用作:

let img = Image(uiImage: UIImage.fromUrl(url: url))

注意:如果使用 UIImage 并加载远程图像,您可能希望异步加载图像,而不是在主线程上,也许在 .onAppear 中 - 但这超出了这个问题的范围.