UIPopoverPresentationController.barButtonItem не работает, похоже, игнорируется

У меня проблема при отображении UIAlertController типа UIActionSheet в iPad. Я знаю, что iPad требуется больше информации для отображения всплывающего окна, но я борюсь с некоторыми странными проблемами.

Я проверяю проблемы совместимости iOS 13 с помощью своего приложения, и похоже, что старый трюк, например, получение представления с performSelector на UIBarButtonItem, больше не работает.

Способ 1

Итак, я делаю это.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    UIView* internalView = (UIView*) [weakSelf.navigationItem.rightBarButtonItem performSelector:@selector(view)];

    menuController.popoverPresentationController.sourceView = weakSelf.navigationController.navigationBar;
    menuController.popoverPresentationController.sourceRect = internalView.frame;
    menuController.popoverPresentationController.canOverlapSourceViewRect = YES;
}

internalView кажется равным нулю вместо получения UIView в более старых версиях iOS. Всплывающее окно отображается в верхнем левом углу экрана, а не рядом с кнопкой панели навигации.

Способ 2

Итак, я пробую сделать это другим способом, на самом деле, "правильным" способом:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    menuController.popoverPresentationController.barButtonItem = weakSelf.navigationItem.rightBarButtonItem;
}

Когда я пытаюсь использовать этот код, приложение вылетает с сообщением, в котором объясняется, что я должен установить sourceView / sourceRect / barButtonItem. Но я говорю ему сделать это.

Завершение работы приложения из-за неперехваченного исключения «NSGenericException», причина: «Ваше приложение представило UIAlertController () стиля UIAlertControllerStyleActionSheet из UISmartNavigationController (). ModalPresentationStyle UIAlertController с этим стилем - UIModalPresentationPopover. Вы должны предоставить информацию о местоположении для этого всплывающего окна через popoverPresentationController контроллера предупреждений. Вы должны предоставить либо sourceView и sourceRect, либо barButtonItem. Если эта информация неизвестна, когда вы представляете контроллер предупреждений, вы можете предоставить ее в методе UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation.

Я тоже пробую с UIPopoverPresentationControllerDelegate, но получаю те же результаты.

Я проверил и перепроверил, weakSelf.navigationItem.rightBarButtonItem не равен нулю и установил на кнопку правой панели. Думаю, мне не хватает чего-то огромного, но что?


person doubotis    schedule 06.09.2019    source источник
comment
Путь 1 никогда не был правильным. Способ 2 правильный, но вам нужно позвонить в нужное время и в нужном месте. И проверять на iPad незачем. Один и тот же код действует на всех устройствах. Вам следует обновить свой вопрос, указав больше кода для Way 2. Покажите весь соответствующий код для создания, настройки и отображения листа действий.   -  person rmaddy    schedule 09.09.2019
comment
Вы нашли решение проблемы? У меня такая же проблема после обновления до iOS 13.   -  person Herbert Bay    schedule 23.09.2019


Ответы (1)


В документации Apple имеется ссылка на эту страницу. https://developer.apple.com/documentation/uikit/windows_and_popover/documentation/uikit/windows_and_potent_info/displaying Однако пример кода ссылается на объект optionsControl, который никогда не определялся. Я могу получить несколько вариантов сборки, развертывания и запуска, но все они вылетают с аналогичной ошибкой, например: Завершение работы приложения из-за неперехваченного исключения «NSGenericException», причина: «UIPopoverPresentationController () должен иметь не-nil sourceView или barButtonItem, установленный перед презентацией. происходит.' Наконец, после 3 дней чтения я обнаружил, что эта страница вылетает из-за сбоя UIActivityViewController на iPad с iOS 8 который помог мне создать рабочую версию ниже. Что на удивление намного проще, чем все, что я пробовал. Ключом является установка sourceView контроллера на родительский вид, который для меня был object.view, потому что объект является ссылкой на родительский контроллер представления, переданный в качестве отправителя.

static func transmitAirDrop(object: ProjectOrganizerMasterViewController) {
    NSLog("UTVCU.transmitAirDrop")
    if (StatusReportSettings.supportsAirdrop() == false) {
        self.sendMultipleXMLEmail(object: object)
        return;
    }
    let myDelegate : StatusReportAppDelegate = UITableViewController.sharedDelegate()
    let documentsDirectory : String = UITableViewController.persistProjectFiles(managedObjectContext: object.managedObjectContext, delegate: myDelegate as! ProjectOrganizerAppDelegate)

    let backupZipFileName : String = UITableViewController.backupExportZipFileName(StatusReportSettings.appSpecificFileName())!

    let password1 : String = object.passwordPromptController?.textFields?.first?.text ?? ""
    let backupZipFilePath : String = StatusReportMasterViewController.createPasswordProtectedExportZipFile(password1: password1, documentsDirectory: documentsDirectory)

    let url : URL = URL.init(fileURLWithPath: backupZipFilePath)
    NSLog("transmitAirDrop() url ->%@", url.path);



    let objectsToShare : NSArray = [url]

    NSLog("UTVCU.transmitAirDrop presentViewController calling");

    let controller = UIActivityViewController(activityItems: [url], applicationActivities: nil)
    controller.excludedActivityTypes = [.postToFacebook,
        .postToTwitter,
        .print,
        .copyToPasteboard,
        .assignToContact,
        .saveToCameraRoll]

    controller.popoverPresentationController?.sourceView = object.view


    object.present(controller, animated: true, completion: nil)


    NSLog("UTVCU.transmitAirDrop presentViewController returned");

}
person Larry Ricker    schedule 24.09.2019