SwiftUI ShareLink在显示共享工作表之前运行代码



我有一个ShareLink来共享图像

ShareLink(item: image) {
Image(systemName: "square.and.arrow.up")
}

现在,在我可以分享这个图像之前,我必须用一些功能生成它

@State var image: UIImage
var getImage() {
// some code that updates @State variable
}

我的ShareLink本身在上下文菜单中。我的问题是,每次刷新视图或打开上下文菜单时生成此图像(调用getImage()函数(的成本太高。如果用户点击这个ShareLink,然后运行,结果显示在共享工作表中,我有什么方法可以运行代码吗?

注意:我知道这是可能的,使用UIKit作为后备来生成共享表,使用这样的函数:

func actionSheet() {
guard let urlShare = URL(string: "https://developer.apple.com/xcode/swiftui/") else { return }
let activityVC = UIActivityViewController(activityItems: [urlShare], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(activityVC, animated: true, completion: nil)
}

如本文所示:https://medium.com/swift-productions/sharesheet-uiactivityviewcontroller-swiftui-47abcd69aba6

相反,我想知道是否有一种方法可以用新的ios16ShareLink做到这一点


编辑我还没能让它与Sharelink一起工作。以下是我正在使用的变通方法:

Button {
shareCollage()
} label: {
Label("Share Collage", systemImage: "square.and.arrow.up")
}

它调用

func shareCollage() {
Task {
if let screenshot = await takeScreenshot() {
let activityVC = UIActivityViewController(activityItems: [screenshot], applicationActivities: nil)

if UIDevice.current.userInterfaceIdiom == .pad {
// otherwise iPad crashes
let thisViewVC = UIHostingController(rootView: self)
activityVC.popoverPresentationController?.sourceView = thisViewVC.view
}

UIApplication.shared.connectedScenes.flatMap {($0 as? UIWindowScene)?.windows ?? []}.first {$0.isKeyWindow}?.rootViewController?.present(activityVC, animated: true, completion: nil)
}
}
}

来源:https://github.com/charelF/StickerPaste/blob/main/StickerPaste/ContentView.swift

这对我有效:

let img = ImageModel(getImage: getImage)
ShareLink(item: img, preview: SharePreview(
"shareImage",
image: img
)) {
Label("shareImage", systemImage: "photo")
}

struct ImageModel: Transferable {
let getImage: () async -> UIImage?
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(exportedContentType: .jpeg) { item in
try await { () -> Data in
if let img = await item.getImage(), let jpeg = img.jpegData(compressionQuality: 0.6) {
return jpeg
} else {
throw ExportImageError.noImageFound
}
}()
}
}
}

错误:

enum ExportImageError: Error {
case noImageFound
}

我在这里遇到的唯一问题是getImage()被调用两次,一次用于预览,另一次用于导出本身。你不能使用预览,就像这样:

ShareLink(item: ImageModel(getImage: shareImage), preview: SharePreview(
"shareImage",
image: Image("photo")
)) {
Label("shareImage", systemImage: "text.below.photo.fill")
}

或者以某种方式缓存结果。也许还有更好的方法。

我使用@State var imageForShare: ImageFile? = nil作为要共享的图像。

我不认为每次视图刷新时都需要生成图像。只要图像的内容发生变化,就只生成图像(以async方式(,这样SwiftUI就知道何时需要更新图像。

由于异步生成是在后台工作的,它不应该影响视图渲染。

相关内容

最新更新