J'ai une question concernant la méthode de délégué qui n'a pas été appelée pour DocumentPickerViewController, voici l'arrière-plan, j'ai juste besoin d'importer la ressource disponible à partir de mon application Fichiers et pour cette raison, j'utilise UIDocumentPickerViewController.
J'ai un autre ViewController auquel j'ajoute la vue de documentPickerViewController en tant que sous-vue et ajoute son délégué. Le code de mon ViewController va comme ceci.
UIDocumentPickerViewController *dc = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:[self UTITypes] inMode:UIDocumentPickerModeImport];
dc.delegate = self;
[MainVC presentViewController:dc animated:YES completion:nil];
Maintenant que je vois pickercontroller est ouvert et quand je clique sur Annuler documentPickerWasCancelled est appelé mais quand je sélectionne un file documentPicker (_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL] n'est pas appelé.
J'ai essayé de plonger à ma grande surprise ce que je vois est au lieu de montrer mon ViewController auquel j'ajoute la vue du sélecteur en tant que sous-vue si j'ajoute directement pickerViewController comme ceci
var documentPickerController: UIDocumentPickerViewController!
let supportedUTI = [kUTTypeImage,kUTTypeSpreadsheet,kUTTypePresentation,kUTTypeDatabase,kUTTypeFolder,kUTTypeZipArchive,kUTTypeVideo, kUTTypeAudiovisualContent]
documentPickerController = UIDocumentPickerViewController.init(documentTypes: supportedUTI as [String], in: .import)
documentPickerController.delegate = self
documentPickerController.allowsMultipleSelection = false
view.addSubview(documentPickerController.view)
les deux méthodes de délégué sont appelées très bien. Je ne comprends pas pourquoi. Quelqu'un peut-il s'il vous plaît aider moi ici !! Merci d'avance !!
3 Réponses :
La réponse est simple: ceci est hérité d'un UIViewController. Si vous ajoutez simplement la vue de viewController à votre vue, les méthodes de délégué ne sont pas appelées. Un ViewController a son propre cycle de vie. Veuillez lire ici: https://developer.apple.com / documentation / uikit / uidocumentpickerviewcontroller
Alors, excusez-vous de vous tromper. Bien sûr, vous pouvez ajouter un sous-viewController affichant uniquement sa vue. Mais: je pense que cela ne devrait pas être le cas d'utilisation. Il s'agit d'un ViewController plein écran conforme aux guides de conception d'Apple lui-même. Cela étant dit, vous devriez le présenter avec:
func addPicker() {
var documentPickerController: UIDocumentPickerViewController!
documentPickerController = UIDocumentPickerViewController(documentTypes: [String(kUTTypePDF)], in: .import)
documentPickerController.delegate = self
documentPickerController.allowsMultipleSelection = false
present(documentPickerController, animated: true, completion: nil)
}
Il y a des bogues signalés où le développeur a découvert que la vue était rejetée avant que le délégué ne soit appelé. Pour autant que je l'ai vu, ce comportement a été introduit avec ios11 et s'est produit également lorsque le viewController a été présenté. Je ne peux pas vraiment dire si cela est corrigé ou non ni si ce comportement est lié à l'afficher comme une sous-vue. (Je pense qu'il est en quelque sorte corrigé car il fonctionne avec un viewController présenté)
Quoi qu'il en soit, vous devriez simplement le présenter comme écrit ci-dessus et vous êtes prêt à partir.
mais alors pourquoi le rappel annulé fonctionne-t-il? Si j'ai besoin de mettre en œuvre la manière dont je le souhaite, pouvez-vous me suggérer comment je peux le faire? Merci!!
Veuillez consulter ma réponse mise à jour. Il semble qu'il y ait un bug. Mais comme je l'ai écrit: il suffit de le présenter.
J'ai donc eu exactement le même problème, la méthode déléguée documentPickerWasCancelled est appelée mais le didPickDocumentsAt ne serait pas appelé. de la logique de délégation / présentation dans mon contrôleur de vue de base, les méthodes UIPickerDelegate ont fonctionné comme prévu. Cela m'a fait savoir qu'il n'y avait aucun problème de type de configuration bloquant la fonctionnalité.
Je ne sais pas exactement quel est le problème, mais il semble que si le sélecteur de document est présenté sur une hiérarchie de vues complexe, quelque chose se brise .
Ce que j'ai fini par faire pour contourner ce problème a été de créer une nouvelle fenêtre et d'y présenter le sélecteur de documents:
func showDocumentPicker() {
let documentTypes = ["public.image", "com.adobe.pdf"]
let picker = UIDocumentPickerViewController(documentTypes: documentTypes, in: .import)
picker.delegate = self
picker.allowsMultipleSelection = true
picker.modalPresentationStyle = .formSheet
let window = UIWindow(frame: UIScreen.main.bounds)
let newWindowBaseVC = UIViewController()
newWindowBaseVC.view.backgroundColor = UIColor.clear
window.rootViewController = newWindowBaseVC
window.windowLevel = UIWindow.Level.alert
window.makeKeyAndVisible()
newWindowBaseVC.present(picker, animated: false, completion: nil)
}
La raison est que le délégué est désalloué si vous ne le placez pas dans une variable en dehors de la fonction.
Si vous êtes dans un environnement statique, vous pouvez créer un délégué var statique: DocumentPickerDelegateClass par exemple; sinon, dans un UIViewController, créez simplement le délégué var: DocumentPickerDelegateClass
Dans tous les cas, placez la variable en haut, où ne peut pas être libéré. Soyez prudent lorsque vous choisissez l'option "statique", vous devez l'utiliser avec précaution.
Quelle version d'iOS utilisez-vous?
documentPicker (_: didPickDocumentsAt :)(Array of URL) a été ajouté avec iOS 11, tandis quedocumentPicker (_: didPickDocumentAt :)(URL unique) était alors obsolète, mais est utilisé par les versions précédentes.