SwiftUI • 如何实现半屏ShareSheet?

2024-05-05

我在我的项目中实现了一个 ShareSheetSwiftUI App using UIViewControllerRepresentable.


Code

struct ShareView: UIViewControllerRepresentable {
    typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
    
    let activityItems: [Any] = ["Some Text"]
    let applicationActivities: [UIActivity]? = nil
    let excludedActivityTypes: [UIActivity.ActivityType]? = nil
    let callback: Callback? = nil
    
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
        controller.excludedActivityTypes = excludedActivityTypes
        controller.completionWithItemsHandler = callback
        return controller
    }
    
    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
        // ...
    }
}

// Presentation
View()
    .sheet(isPresented: $showShareSheet) {
        ShareView()
    }

Problem:这效果很好,但是Share Sheet始终覆盖整个屏幕。我见过Share Sheets在其他仅覆盖屏幕下半部分的应用程序中。我怎样才能实现这个目标?


UIKit解决方案。

我已提出UIActivityViewController在大多数控制器的顶部。

class ShareView {
    static let shared = ShareView()
    typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
    
    let activityItems: [Any] = ["Some Text"]
    let applicationActivities: [UIActivity]? = nil
    let excludedActivityTypes: [UIActivity.ActivityType]? = nil
    let callback: Callback? = nil
    
    func open(callback: Callback? = nil) {
        let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
        controller.excludedActivityTypes = excludedActivityTypes
        controller.completionWithItemsHandler = callback
        UIWindow.getTopViewController()?.present(controller, animated: true, completion: nil)
    }
}

Usage:

struct ContentView: View {
    var body: some View {
        Button("Open Share Sheet") {
            ShareView.shared.open()
        }
    }
}

辅助函数来自here https://stackoverflow.com/a/64675926/14733292

extension UIWindow {
    static func getTopViewController() -> UIViewController? {
        if #available(iOS 13, *){
            let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
            
            if var topController = keyWindow?.rootViewController {
                while let presentedViewController = topController.presentedViewController {
                    topController = presentedViewController
                }
                return topController
            }
        } else {
            if var topController = UIApplication.shared.keyWindow?.rootViewController {
                while let presentedViewController = topController.presentedViewController {
                    topController = presentedViewController
                }
                return topController
            }
        }
        return nil
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SwiftUI • 如何实现半屏ShareSheet? 的相关文章

随机推荐