我正在尝试创建一个共享表来共享
Text
,它在 iOS 14 中运行良好,但在 iOS 15 中它告诉我这一点
'windows' 在 iOS 15.0 中已弃用:在 a 上使用 UIWindowScene.windows 而是相关的窗口场景。
如何使用 SwiftUI 使其在 iOS 15 上运行
Button {
let TextoCompartido = "Hola 😀 "
let AV = UIActivityViewController(activityItems: [TextoCompartido], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(AV, animated: true, completion: nil)
}
我认为直接使用 SwiftUI API 会为您提供最好的服务。一般来说,我会遵循以下步骤。
View
,命名为 ActivityView
,遵循 UIViewControllerRepresentable
。这将允许您将 UIActivityViewController
引入 SwiftUI。Identifiable
结构体来包含您想要在 ActivityView
中显示的文本。创建此类型将允许您使用 SwiftUI sheet API 并利用 SwiftUI 状态来告诉应用程序何时显示新的 ActivityView
。@State
变量,该变量将保留您的 Identifiable
文本构造。当此变量发生变化时,sheet API将执行回调。ActivityView
。下面的代码应该可以帮助您入门。
import UIKit
import SwiftUI
// 1. Activity View
struct ActivityView: UIViewControllerRepresentable {
let text: String
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
return UIActivityViewController(activityItems: [text], applicationActivities: nil)
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityView>) {}
}
// 2. Share Text
struct ShareText: Identifiable {
let id = UUID()
let text: String
}
struct ContentView: View {
// 3. Share Text State
@State var shareText: ShareText?
var body: some View {
VStack {
Button("Show Activity View") {
// 4. New Identifiable Share Text
shareText = ShareText(text: "Hola 😀")
}
.padding()
}
// 5. Sheet to display Share Text
.sheet(item: $shareText) { shareText in
ActivityView(text: shareText.text)
}
}
}
在 iOS 15 中使用 SwiftUI 进行测试
func shareViaActionSheet() {
if vedioData.vedioURL != nil {
let activityVC = UIActivityViewController(activityItems: [vedioData.vedioURL as Any], applicationActivities: nil)
UIApplication.shared.currentUIWindow()?.rootViewController?.present(activityVC, animated: true, completion: nil)
}
}
为了避免 iOS 15 方法弃用警告,请使用此扩展
public extension UIApplication {
func currentUIWindow() -> UIWindow? {
let connectedScenes = UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.compactMap { $0 as? UIWindowScene }
let window = connectedScenes.first?
.windows
.first { $0.isKeyWindow }
return window
}
}
iOS 16 包含
ShareLink
视图,其工作方式如下:
Gallery(...)
.toolbar {
ShareLink(item: image, preview: SharePreview("Birthday Effects"))
}
来源:https://developer.apple.com/videos/play/wwdc2022/10052/
时间码偏移:25分28秒
为了避免警告,请更改检索窗口场景的方式。 执行以下操作:
Button {
let TextoCompartido = "Hola 😀 "
let AV = UIActivityViewController(activityItems: [TextoCompartido], applicationActivities: nil)
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
windowScene?.keyWindow?.rootViewController?.present(AV, animated: true, completion: nil)
}
您可以使用以下答案尝试以下操作:如何使用 AdMob 横幅删除消息“‘windows’在 iOS 15.0 中已弃用:在相关窗口场景上使用 UIWindowScene.windows”?
请注意,您的代码对我有用,但编译器给出了弃用警告。
public extension UIApplication {
func currentUIWindow() -> UIWindow? {
let connectedScenes = UIApplication.shared.connectedScenes
.filter({
$0.activationState == .foregroundActive})
.compactMap({$0 as? UIWindowScene})
let window = connectedScenes.first?
.windows
.first { $0.isKeyWindow }
return window
}
}
struct ContentView: View {
let TextoCompartido = "Hola 😀 "
var body: some View {
Button(action: {
let AV = UIActivityViewController(activityItems: [TextoCompartido], applicationActivities: nil)
UIApplication.shared.currentUIWindow()?.rootViewController?.present(AV, animated: true, completion: nil)
// This works for me, but the compiler give the deprecation warning
// UIApplication.shared.windows.first?.rootViewController?.present(AV, animated: true, completion: nil)
}) {
Text("Hola click me")
}
}
}
// iOS 16+,Swift 5
var rootViewController: UIViewController? {
let connectedScenes = UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.compactMap { $0 as? UIWindowScene }
let window = connectedScenes.first?.windows.first { $0.isKeyWindow }
let rootViewController = window?.rootViewController
return rootViewController
}
func topViewController(of viewController: UIViewController? = rootViewController) -> UIViewController? {
if let navigationController = viewController as? UINavigationController {
return topViewController(of: navigationController.visibleViewController)
}
if let tabController = viewController as? UITabBarController {
if let selected = tabController.selectedViewController {
return topViewController(of: selected)
}
}
if let presented = viewController?.presentedViewController {
return topViewController(of: presented)
}
return viewController
}