如何将UIActivityViewController与SwiftUI的ScrollView集成?

6
在一个项目中,我有一个ScrollView包围着一个VStack的项,每个项都有一个按钮来触发通过UIActivityViewController的活动视图,但是活动视图没有出现。
我已经将该项目简化为以下代码,成功显示了活动视图,但是当我取消注释ScrollView时,在按下"打开活动视图"按钮时,活动视图不再出现。
谢谢!
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)
            }
        }
//    }
    }
}
1个回答

5
这是一个可行的方法(经过Xcode 11.2/iOS 13.2测试)...不需要额外的包装主机控制器,最好使用原生的SwiftUI工具进行展示。
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()
    }
}

谢谢你的回答。你知道如何放入本地变体吗?还请参考以下问题:https://dev59.com/qFMI5IYBdhLWcg3wPo8a 你的解决方案导致表格横跨整个显示屏。 - Jonas Deichelmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接