我正在尝试使用
ContentMenu
来允许用户执行诸如将图像保存到相机胶卷等操作。目前在代码中,显示图像的值是 Image
类型,所以我创建了一个函数,应该将其转换为 UIImage
类型的值,然后图像将通过 UIImageWriteToSavedPhotosAlbum()
保存到相机胶卷中。该代码有效,但是当我查看相机胶卷中保存的图像时,它显示为全黑图像,而不是实际图像本身。
转换的代码如下:
extension Image {
func asUIImage() -> UIImage? {
// Create a UIView
let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
// Create a hosting controller with the SwiftUI Image
let hostingController = UIHostingController(rootView: self)
// Assign the frame to the hosting controller
hostingController.view.frame = uiView.bounds
// Add the hosting controller's view to the UIView
uiView.addSubview(hostingController.view)
// Make the snapshot of the hosting controller's view
UIGraphicsBeginImageContextWithOptions(uiView.bounds.size, uiView.isOpaque, 0.0)
defer { UIGraphicsEndImageContext() }
guard let context = UIGraphicsGetCurrentContext() else { return nil }
uiView.layer.render(in: context)
let uiImage = UIGraphicsGetImageFromCurrentImageContext()
return uiImage
}
}
这里称为:
func manyMediaView(media: [MediaOBJ]) -> some View {
GeometryReader { geo in
TabView {
ForEach(media.indices, id: \.self) { index in
AsyncImage(url: media[index].link) { phase in
switch phase {
case .success(let image):
image
.resizable()
.aspectRatio(contentMode: .fill)
.contentShape(Rectangle())
.onTapGesture {
selectedImageIndex = index
showFullImage = true
}
.contextMenu {
Button(action: {
// Action to copy the photo
}) {
Text("Copy Photo")
Image(systemName: "doc.on.doc")
}
Button(action: {
// Action to save the photo
if let uiImage = image.asUIImage() {
UIImageWriteToSavedPhotosAlbum(uiImage, nil, nil, nil)
print("Saved successfully!")
} else {
print("Error: Unable to convert Image to UIImage.")
}
}) {
Text("Save Photo")
Image(systemName: "square.and.arrow.down")
}
ShareLink(item: viewModel.post.url) {
Text("Share via ...")
Image(systemName: "square.and.arrow.up")
}
}
case .failure:
DefaultPlaceholder()
.maxHeight(600)
.onAppear {
imageLoadKey = .init()
}
case .empty:
Color.clear
}
}
.tag(index)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
.cornerRadius(16)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
.gesture(
DragGesture().onChanged { value in
if value.translation.width > 50 {
selectedImageIndex = max(selectedImageIndex - 1, 0)
} else if value.translation.width < -50 {
selectedImageIndex = min(selectedImageIndex + 1, media.count - 1)
}
}
)
.fullScreenCover(isPresented: $showFullImage) {
MultiImageGalleryView(imageUrls: media.map { $0.link }, isPresented: $showFullImage, selectedImageIndex: $selectedImageIndex)
}
.onTapGesture {
// Intentionally empty to prevent auto navigation to SinglePostView
}
}
}
我缺少什么才能正确保存图像?
更新:我找到了解决方案。该功能仅正确渲染大小,而不渲染内容本身。它只是用原始图像的大小制作一个新的空白
UIImage
。
这是修改后的正确函数:
extension Image {
func asUIImage() -> UIImage? {
// Create a hosting controller with the SwiftUI Image
let hostingController = UIHostingController(rootView: self)
// Calculate the size needed for rendering
let size = hostingController.sizeThatFits(in: UIScreen.main.bounds.size)
// Set the size for the hosting controller's view
hostingController.view.bounds = CGRect(origin: .zero, size: size)
// Render the hosting controller's view into an image
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { context in
hostingController.view.drawHierarchy(in: hostingController.view.bounds, afterScreenUpdates: true)
}
return image
}
}