编辑:删除所有代码和对UIButton 的引用。
感谢@Matteo_Pacini 对this question 的回复,向我们展示了这项技术。与他的回答(和评论)一样,(1)这很粗糙,(2)我不确定苹果希望我们如何使用UIViewControllerRepresentable,我真的希望他们提供更好的SwiftUI( “SwiftierUI”?)在未来的测试版中替换。
我在UIKit 中做了很多工作,因为我希望它在 iPad 上看起来不错,而弹出窗口需要sourceView。真正的技巧是显示一个(SwiftUI)View,它在视图层次结构中获取UIActivityViewController,并从UIKit 触发present。
我的需要是展示一个单一的图像来分享,所以事情就是朝着这个方向发展的。假设您有一个图像,存储为 @State 变量 - 在我的示例中,图像被称为 vermont.jpg 是的,事情是硬编码的。
首先,创建一个 `UIViewController 类型的 UIKit 类来显示共享弹出框:
class ActivityViewController : UIViewController {
var uiImage:UIImage!
@objc func shareImage() {
let vc = UIActivityViewController(activityItems: [uiImage!], applicationActivities: [])
vc.excludedActivityTypes = [
UIActivity.ActivityType.postToWeibo,
UIActivity.ActivityType.assignToContact,
UIActivity.ActivityType.addToReadingList,
UIActivity.ActivityType.postToVimeo,
UIActivity.ActivityType.postToTencentWeibo
]
present(vc,
animated: true,
completion: nil)
vc.popoverPresentationController?.sourceView = self.view
}
}
主要是:
- 您需要一个“包装器”
UIViewController 才能present 事物。
- 您需要
var uiImage:UIImage! 来设置activityItems。
接下来,将其包装成UIViewControllerRepresentable:
struct SwiftUIActivityViewController : UIViewControllerRepresentable {
let activityViewController = ActivityViewController()
func makeUIViewController(context: Context) -> ActivityViewController {
activityViewController
}
func updateUIViewController(_ uiViewController: ActivityViewController, context: Context) {
//
}
func shareImage(uiImage: UIImage) {
activityViewController.uiImage = uiImage
activityViewController.shareImage()
}
}
唯一需要注意的两件事是:
- 实例化
ActivityViewController 以将其返回到ContentView
- 创建
shareImage(uiImage:UIImage) 来调用它。
最后,你有ContentView:
struct ContentView : View {
let activityViewController = SwiftUIActivityViewController()
@State var uiImage = UIImage(named: "vermont.jpg")
var body: some View {
VStack {
Button(action: {
self.activityViewController.shareImage(uiImage: self.uiImage!)
}) {
ZStack {
Image(systemName:"square.and.arrow.up").renderingMode(.original).font(Font.title.weight(.regular))
activityViewController
}
}.frame(width: 60, height: 60).border(Color.black, width: 2, cornerRadius: 2)
Divider()
Image(uiImage: uiImage!)
}
}
}
请注意,uiImage 有一些硬编码和(呃)强制解包,以及对@State 的不必要使用。这些是因为我打算在旁边使用 `UIImagePickerController 将它们联系在一起。
注意事项:
- 实例化
SwiftUIActivityViewController,并使用shareImage 作为按钮操作。
- 用它来也是按钮显示。别忘了,即使是
UIViewControllerRepresentable 也只是被视为 SwiftUI View!
将图像的名称更改为您项目中的名称,这应该可以。您将获得一个居中的 60x60 按钮,其下方有图片。