ios – Opening share sheet from customized alert

0
17
ios – Opening share sheet from customized alert


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
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here