如何使用催化剂在iOS和MacOS中弹出文档选择器

我正在尝试使用mac催化剂弹出一个文档选择器,但是我得到的只是一个空白屏幕。

所有功能都可以在iPad和iPhone上的ios 13.2.2上正常运行,但不能在macOS 10.15.1 catalina上运行。

有人知道如何使用催化剂在iOS和MacOS中弹出文档选择器吗?

我的权利文件具有:

void

这是显示问题的测试代码。

<key>com.apple.security.app-sandbox</key>
<false/>

我用以下代码处理了一些事情。但这真的是 生意混乱,我觉得这不是答案。

现在我尝试显示同样的问题 uiactivityViewController。我可以使用相同的方法在Mac上显示它,但是 我无法控制显示位置。始终为(0,0)。

import Foundation
import SwiftUI

struct ContentView: View {
@State var isFilePickerShown = false

var body: some View {
    VStack {
        Button(action: { self.isFilePickerShown.toggle() }) {
            Image(systemName: "rectangle.and.paperclip").resizable().frame(width: 70,height: 70)
        }
    }.sheet(isPresented: $isFilePickerShown,onDismiss: {self.isFilePickerShown = false}) {
        DocPickerViewController(callback: self.filePicked,onDismiss: { self.isFilePickerShown = false })
    }
}

func filePicked(_ url: URL) {
    print("\nThe url is: \(url)")
}

}

struct DocPickerViewController: UIViewControllerRepresentable {

private let docTypes: [String] = ["com.adobe.pdf","public.text","public.composite-content"]
var callback: (URL) -> ()
private let onDismiss: () -> Void

init(callback: @escaping (URL) -> (),onDismiss: @escaping () -> Void) {
    self.callback = callback
    self.onDismiss = onDismiss
}

func makeCoordinator() -> Coordinator { Coordinator(self) }

func updateUIViewController(_ uiViewController: UIDocumentPickerViewController,context: UIViewControllerRepresentableContext<DocPickerViewController>) {
}

func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
    let controller = UIDocumentPickerViewController(documentTypes: docTypes,in: .import)
    controller.allowsMultipleSelection = false
    controller.delegate = context.coordinator
    return controller
}

class Coordinator: NSObject,UIDocumentPickerDelegate {
    var parent: DocPickerViewController
    init(_ pickerController: DocPickerViewController) {
        self.parent = pickerController
    }
    func documentPicker(_ controller: UIDocumentPickerViewController,didPickDocumentsAt urls: [URL]) {
        parent.callback(urls[0])
        parent.onDismiss()
    }
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        parent.onDismiss()
    }
}
}

我这样称呼它:

struct FilePicker: UIViewControllerRepresentable {

private let docTypes: [String] = ["com.adobe.pdf","public.composite-content"]
private let controller: FilePickerController?

var callback: (URL) -> ()

private let onDismiss: () -> Void

init(callback: @escaping (URL) -> (),onDismiss: @escaping () -> Void) {
    self.callback = callback
    self.onDismiss = onDismiss
    self.controller = FilePickerController(documentTypes: docTypes,mode: .import)
}

func makeCoordinator() -> Coordinator {
    return Coordinator(self)
}

func updateUIViewController(_ uiViewController: FilePickerController,context: UIViewControllerRepresentableContext<FilePicker>) { }

func makeUIViewController(context: Context) -> FilePickerController {
    return controller!
}

class Coordinator: NSObject,FilePickerControllerDelegate {
    var parent: FilePicker

    init(_ filePicker: FilePicker) {
        self.parent = filePicker
        super.init()
        self.parent.controller?.delegate = self
    }

    func documentPicker(_ controller: FilePickerController,didPickDocumentsAt urls: [URL]) {
        parent.callback(urls[0])
        parent.onDismiss()
    }

    func documentPickerWasCancelled(_ controller: FilePickerController) {
        parent.onDismiss()
    }
}
}


protocol FilePickerControllerDelegate: class {
func documentPickerWasCancelled(_ controller: FilePickerController)
func documentPicker(_ controller: FilePickerController,didPickDocumentsAt urls: [URL])
}

class FilePickerController: UIViewController,UIDocumentPickerDelegate {

weak var delegate: FilePickerControllerDelegate?

let viewController: UIDocumentPickerViewController?

public init(documentTypes: [String],mode: UIDocumentPickerMode) {
    viewController = UIDocumentPickerViewController(documentTypes: documentTypes,in: mode)
    super.init(nibName: nil,bundle: nil)
}

required public init?(coder: NSCoder) {
    viewController = UIDocumentPickerViewController(coder: coder)
    super.init(coder: coder)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let viewController = viewController {
        viewController.delegate = self
        self.present(viewController,animated: animated)
    }
}

func documentPicker(_ controller: UIDocumentPickerViewController,didPickDocumentsAt urls: [URL]) {
    self.dismiss(animated: false) {
        self.delegate?.documentPicker(self,didPickDocumentsAt: urls)
    }
}

func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
    self.dismiss(animated: false) {
        self.delegate?.documentPickerWasCancelled(self)
    }
}

}
lili19890701 回答:如何使用催化剂在iOS和MacOS中弹出文档选择器

适用于所有具有hstdtworkingdog的代码。

import SwiftUI

struct ContentView: View {
    @State private var isFilePickerShown = false
    @State private var picker = DocumentPicker()

    var body: some View {
        VStack {
            Button(action: {
                self.isFilePickerShown.toggle()
                 #if targetEnvironment(macCatalyst)
                UIApplication.shared.windows[0].rootViewController!.present(self.picker.viewController,animated: true)
                #endif
            }) {
                Image(systemName: "rectangle.and.paperclip").resizable().frame(width: 70,height: 70)
            }
        }
        .sheet(isPresented: $isFilePickerShown,onDismiss: {self.isFilePickerShown = false}) {
            DocPickerViewController(callback: self.filePicked,onDismiss: { self.isFilePickerShown = false })
        }
    }

    func filePicked(_ url: URL) {
        print("\nThe url is: \(url)")
    }
}

现在为MacOS创建新的swiftui文件DocumentPicker

import SwiftUI

final class DocumentPicker: NSObject,UIViewControllerRepresentable {
    typealias UIViewControllerType = UIDocumentPickerViewController

    lazy var viewController:UIDocumentPickerViewController = {
        // For picked only folder
        let vc = UIDocumentPickerViewController(documentTypes: ["public.folder"],in: .open)
        // For picked every document
//        let vc = UIDocumentPickerViewController(documentTypes: ["public.data"],in: .open)
        // For picked only images
//        let vc = UIDocumentPickerViewController(documentTypes: ["public.image"],in: .open)
        vc.allowsMultipleSelection = false
//        vc.accessibilityElements = [kFolderActionCode]
//        vc.shouldShowFileExtensions = true
        vc.delegate = self
        return vc
    }()

    func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPicker>) -> UIDocumentPickerViewController {
        viewController.delegate = self
        return viewController
    }

    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController,context: UIViewControllerRepresentableContext<DocumentPicker>) {
    }
}

extension DocumentPicker: UIDocumentPickerDelegate {
    func documentPicker(_ controller: UIDocumentPickerViewController,didPickDocumentsAt urls: [URL]) {
        print(urls)
    }

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        controller.dismiss(animated: true) {
        }
        print("cancelled")
    }
}

此代码使用催化剂在iOS和MacOS中弹出文档选择器。 在MacOS Catalyst上可以使用DocumentPicker类,而在iOS上可以使用DocPickerViewController编写的workingdog(请参见上面的workingdog帖子)

,

解决方法:现有的催化剂选择器控制器

UIApplication.shared.windows[0].rootViewController!.present(self.picker.controller!,animated: true)
,

这是GitHub上Cesare Piersigilli的示例:https://github.com/AndreasPrang/Catalyst-File-Picker

本文链接:https://www.f2er.com/3134105.html

大家都在问