'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
ViewnamedActivityViewthat adheres toUIViewControllerRepresentable. This will allow you to bringUIActivityViewControllerto SwiftUI. - Create an
Identifiablestruct 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 newActivityViewto be shown. - Create an optional
@Statevariable that will hold on to yourIdentifiabletext 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
ActivityViewwhich 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 |
