如何将 UIActivityViewController 与 SwiftUI 的 ScrollView 集成? [英] How to integrate UIActivityViewController with SwiftUI's ScrollView?

查看:24
本文介绍了如何将 UIActivityViewController 与 SwiftUI 的 ScrollView 集成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个项目中,我有一个 ScrollView 围绕着一个 VStack 的项目,每个项目都有一个按钮来通过 UIActivityViewController 触发 Activity View,但活动视图没有出现.

In a project I have a ScrollView surrounding a VStack of items which each have a button to trigger the Activity View via the UIActivityViewController, but the Activity View doesn't appear.

我已将项目缩减为以下代码,该代码成功显示了 Activity View,但是当我取消注释 ScrollView 时,按下 "Open Activity 时不再出现 Activity View查看" 按钮.

I've reduced the project to the following code, which successfully displays the Activity View, but when I uncomment the ScrollView, the Activity View no longer appears when pressing the "Open Activity View" button.

谢谢!

import SwiftUI

class UIActivityViewControllerHost: UIViewController {
    var url: String = ""
    var completionWithItemsHandler: UIActivityViewController.CompletionWithItemsHandler? = nil

    override func viewDidAppear(_ animated: Bool) {
        let vc = UIActivityViewController(
            activityItems: [NSURL(string: url)!],
            applicationActivities: nil
        )
        vc.completionWithItemsHandler = completionWithItemsHandler
        present(vc, animated: true, completion: nil)
        super.viewDidAppear(animated)
    }
}

struct ActivityView: UIViewControllerRepresentable {
    var url: String
    @Binding var showing: Bool

    func makeUIViewController(context: Context) -> UIActivityViewControllerHost {
        let result = UIActivityViewControllerHost()
        result.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
            self.showing = false
        }
        return result
    }
    func updateUIViewController(_ uiViewController: UIActivityViewControllerHost, context: Context) {
        uiViewController.url = url
    }
}

struct ContentView: View {
    @State var showSheet = false

    var body: some View {
//        ScrollView {
        Group {
            Button(action: {
                self.showSheet.toggle()
              }) {
                  Text("Open Activity View")
              }
            if showSheet {
                ActivityView(url: "https://www.wikipedia.org", showing: $showSheet)
                    .frame(width: 0, height: 0)
            }
        }
//    }
    }
}

推荐答案

这是有效的方法(使用 Xcode 11.2/iOS 13.2 测试)...不需要额外的包装器主机控制器,最好使用用于演示的原生 SwiftUI 工具.

Here is the approach that works (tested with Xcode 11.2/iOS 13.2)... The extra wrapper host controller is not needed, and it is better to use native SwiftUI instruments for presentation.

import SwiftUI

struct ActivityView: UIViewControllerRepresentable {
    var url: String
    @Binding var showing: Bool

    func makeUIViewController(context: Context) -> UIActivityViewController {
        let vc = UIActivityViewController(
            activityItems: [NSURL(string: url)!],
            applicationActivities: nil
        )
        vc.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
            self.showing = false
        }
        return vc
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
    }
}

struct TestUIActivityView: View {
    @State var showSheet = false

    var body: some View {
        ScrollView {
        Group {
            Button(action: {
                self.showSheet.toggle()
              }) {
                  Text("Open Activity View")
              }
            .sheet(isPresented: $showSheet) {
                ActivityView(url: "https://www.wikipedia.org", showing: self.$showSheet)
            }
        }
    }
    }
}

struct TestUIActivityView_Previews: PreviewProvider {
    static var previews: some View {
        TestUIActivityView()
    }
}

这篇关于如何将 UIActivityViewController 与 SwiftUI 的 ScrollView 集成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆