web-dev-qa-db-ja.com

Catalystを使用してIOSおよびMacOSでドキュメントピッカーをポップアップする方法

私はMac Catalystを使って文書ピッカーをポップアップしようとしていますが、私が得るのは空白の画面です。

すべてがiPadとiPhoneでiOS 13.2.2でうまく機能しますが、MacOS 10.15.1カタリナではありません。

Catalystを使用してIOSとMacOSの両方で文書ピッカーをポップアップする方法は誰でも知っていますか?

私の資格ファイルを持っている:

<key>com.Apple.security.app-sandbox</key>
<false/>
 _

これが問題を示すテストコードです。

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()
    }
}
}
 _

次のコードで何か行って何かがありました。しかし本当にこれは乱雑なビジネスです、そして、私はこれが答えではないと感じます。

これで、UIActivityViewControllerを表示しようとしているのと同じ問題があります。同じアプローチを使用してMac上に表示できますが、表示されている場所を制御できません。それは常に(0,0)です。

struct FilePicker: UIViewControllerRepresentable {

private let docTypes: [String] = ["com.Adobe.pdf", "public.text", "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)
    }
}

}
 _

私はそれをこのように呼び出します:

.sheet(isPresented: $isShown, onDismiss: {self.isShown = false}) {
        #if targetEnvironment(macCatalyst)
            FilePicker(callback: self.filePicked, onDismiss: { self.isShown = false })
        #else
            DocPickerViewController(callback: self.filePicked, onDismiss: { self.isShown = false })
        #endif
    }
 _
5
workingdog

回避策:触媒用プレゼントピッカーコントローラ

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