'Create a share sheet in iOS 15 with swiftUI
I am trying to create a share sheet to share a Text, it was working fine in iOS 14 but in iOS 15 it tells me that
"'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead".
how can I make it work on iOS 15 with SwiftUI
Button {
let TextoCompartido = "Hola 😀 "
let AV = UIActivityViewController(activityItems: [TextoCompartido], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(AV, animated: true, completion: nil)
}
Solution 1:[1]
I think you would be best served using SwiftUI APIs directly. Generally, I would follow these steps.
- Create SwiftUI
View
namedActivityView
that adheres toUIViewControllerRepresentable
. This will allow you to bringUIActivityViewController
to SwiftUI. - Create an
Identifiable
struct to contain the text you'd like to display in theActivityView
. Making this type will allow you to use the SwiftUI sheet API and leverage SwiftUI state to tell the app when a newActivityView
to be shown. - Create an optional
@State
variable that will hold on to yourIdentifiable
text construct. When this variable changes, the sheet API will perform the callback. - When the button is tapped, update the state of the variable set in step 3.
- Use the sheet API to create an
ActivityView
which will be presented to your user.
The code below should help get you started.
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)
}
}
}
Solution 2:[2]
you could try the following using the answer from: How to get rid of message " 'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead" with AdMob banner?
Note that your code works for me, but the compiler give the deprecation warning.
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")
}
}
}
Solution 3:[3]
To avoid warning, change the way you retrieve the window scene. Do the following:
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)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | esreli |
Solution 2 | workingdog support Ukraine |
Solution 3 | Alessandro Pace |