I’ve a fancy app written in SwiftUI wherein I’m making an attempt to open share sheet from a customized alert. I’ve written pattern app wherein share sheet by no means opens from alert. I additionally want to current customized alert over any view/sheets that is open within the app, therefore I’m presenting it as full display cowl.
Customized alert has 2 buttons – OK and Share Sheet. When “Share Sheet” button is tapped, app ought to open share sheet.
Sharing my code for most important view, customized alert view and share sheet code. What am doing mistaken due to which share sheet is not opening?
import Basis
import SwiftUI
import UIKit
@MainActor
class ContentViewModel: ObservableObject {
@Revealed var showAlert = false
}
struct ContentView: View {
@StateObject var contentViewModel: ContentViewModel = ContentViewModel()
var physique: some View {
VStack {
Button {
contentViewModel.showAlert = true
} label: {
Textual content("Faucet me to open a customized alert")
}
.offset(y: -200)
}
.showCustomAlert(isPresented: $contentViewModel.showAlert)
}
}
// MARK: Code for customized alert view.
struct CustomAlertView: ViewModifier {
@Binding var isPresented: Bool
@Atmosphere(.dismiss) var dismiss
init(isPresented: Binding) {
self._isPresented = isPresented
}
func physique(content material: Content material) -> some View {
content material.fullScreenCover(isPresented: $isPresented) {
alertContent().presentationBackground(Coloration.black.opacity(0.3))
}
.transaction { transaction in
transaction.disablesAnimations = true
}
}
@ViewBuilder
personal func alertContent() -> some View {
GeometryReader { geometry in
if self.$isPresented.wrappedValue {
VStack {
Textual content("It is a customized alert.")
.font(.title2).daring().multilineTextAlignment(.heart)
.padding([.leading, .trailing], 20.0).padding(.prime, 16.0)
Spacer()
Textual content("Faucet 'Share Sheet' button to open share sheet.").foregroundColor(Coloration.secondary).font(.physique).multilineTextAlignment(.heart)
.padding([.leading, .trailing], 18.0).padding(.prime, 16.0)
Spacer()
HStack {
Button {
self.$isPresented.wrappedValue.toggle()
} label: {
Textual content("OK")
}
.body(width: 200, top: 50)
Button {
// Open share sheet and dismiss the alert.
ShareSheet.shared.open(topic: "That is topic", content material: "That is content material")
self.$isPresented.wrappedValue.toggle()
} label: {
Textual content("Share Sheet")
}
.body(width: 200, top: 50)
}.padding(.prime, 16.0).padding(.backside, 24.0)
}
.fixedSize(horizontal: false, vertical: true)
.background(Coloration.grey.opacity(0.75))
.cornerRadius(28)
.clipped()
.padding([.leading, .trailing], 5.0)
.place(x: geometry.measurement.width/2, y: geometry.measurement.top/2)
.body(width: 315.0)
}
}
}
}
extension View {
func showCustomAlert(isPresented: Binding) -> some View {
return modifier(CustomAlertView(isPresented: isPresented))
}
}
// MARK: Code for share sheet.
class ShareSheet {
static let shared = ShareSheet()
typealias Callback = (_ activityType: UIActivity.ActivityType?, _ accomplished: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
let applicationActivities: [UIActivity]? = nil
let excludedActivityTypes: [UIActivity.ActivityType]? = nil
func open(topic: String, content material: String, callback: Callback? = nil) {
let controller = UIActivityViewController(activityItems: [MessageWithSubject(subject: subject, message: content)],
applicationActivities: applicationActivities)
controller.excludedActivityTypes = excludedActivityTypes
controller.completionWithItemsHandler = callback
UIWindow.getTopViewController()?.current(controller, animated: true, completion: nil)
}
}
class MessageWithSubject: NSObject, UIActivityItemSource {
let topic:String
let message:String
init(topic: String, message: String) {
self.topic = topic
self.message = message
tremendous.init()
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return message
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
let activityTypeId = activityType?.rawValue ?? ""
if (activityTypeId == "com.apple.mobilenotes.SharingExtension") || (activityTypeId == "com.google.Gmail.ShareExtension") {
let mixed = topic + "nn" + message
return mixed
}
return message
}
func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
return topic
}
}
extension UIWindow {
static func getTopViewController() -> UIViewController? {
let keyWindow = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.home windows.first
if var topController = keyWindow?.rootViewController {
whereas let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
return topController
}
return nil
}
}