adaptivePresentationStyle not Triggering для UIPopoverPresentationControllerDelegate на компактных (iPhone) устройствах - PullRequest
0 голосов
/ 18 марта 2019

Я пытаюсь отобразить один UIViewController как поповер из другого.Для этого я установил следующее ...

func showPopover(ofViewController popoverViewController: UIViewController, sender: UIView) {
    popoverViewController.modalPresentationStyle = .popover
    popoverViewController.popoverPresentationController?.sourceView = sender
    popoverViewController.popoverPresentationController?.sourceRect = sender.bounds
    popoverViewController.popoverPresentationController?.delegate = self
    self.present(popoverViewController, animated: true, completion: nil)
}

Тем не менее, новый VC всегда отображается в виде полноэкранного модального представления на компактных устройствах, а не в виде реального поповера.Исходя из того, что я прочитал здесь & здесь , это нормальное поведение, но его можно настраивать с помощью делегирования.

Я объявил представляемый VC как реализующий UIPopoverPresentationControllerDelegate, установить его в качестве делегата и реализовать необходимые методы;однако методы делегирования никогда не вызываются.Это означает, что «поповер» по-прежнему отображается модально, независимо от того.

Любой совет будет приветствоваться.

Некоторые другие выноски:

  • viewControllerForAdaptivePresentationStyle вызывается , если перед ним добавлен маркер @objc, но для остальных это не работает.
  • Xcode выдает предупреждение для каждого: Метод экземпляра... почти соответствует необязательному требованию ... протокола 'UIAdaptivePresentationControllerDelegate' ;однако сигнатура метода соответствует 100%.Не уверен, что это экземпляр этой ошибки , которая, как говорят некоторые, все еще существует в Xcode 10.1.

Спасибо.

Реализованы функции делегирования:

func adaptivePresentationStyle(for: UIPresentationController) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.popover
}

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.popover
}

func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
    switch style {
    case .fullScreen: // Configuration for full-screen
    default: return controller.presentedViewController
    }
}

1 Ответ

0 голосов
/ 21 марта 2019

Спасибо Paulw11 за подтверждение того, что проблема была вызвана внедрением кода в расширение из UIViewController. Это приводило к странному поведению, в результате чего код вызывался не так, как обычно.

При переносе в общий подкласс из UIViewController все проблемы были решены:

  • Метод adaptivePresentationStyle никогда не вызывается.
  • Метод viewControllerForAdaptivePresentationStyle вызывается только в том случае, если ему предшествует тег @objc.
  • Xcode, дающий Метод экземпляра ... почти соответствует необязательному требованию ... протокола 'UIAdaptivePresentationControllerDelegate' ошибки.

Исправленный код выглядит следующим образом для тех, кто ищет ту же функциональность.

class CustomViewController: UIViewController {

    func showPopover(ofViewController popoverViewController: UIViewController, originView: UIView) {
        popoverViewController.modalPresentationStyle = UIModalPresentationStyle.popover
        if let popoverController = popoverViewController.popoverPresentationController {
            popoverController.delegate = self
            popoverController.sourceView = originView
            popoverController.sourceRect = originView.bounds
            popoverController.backgroundColor = popoverViewController.view.backgroundColor
            popoverController.permittedArrowDirections = UIPopoverArrowDirection.any
        }
        self.present(popoverViewController, animated: true)
    }
}

extension CustomViewController: UIPopoverPresentationControllerDelegate {

    func adaptivePresentationStyle(for: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.none
        //return UIModalPresentationStyle.fullScreen
    }

    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        if traitCollection.horizontalSizeClass == .compact {
            return UIModalPresentationStyle.none
            //return UIModalPresentationStyle.fullScreen
        }
        //return UIModalPresentationStyle.fullScreen
        return UIModalPresentationStyle.none
    }

    func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
        switch style {
        case .fullScreen: // Configuration for full-screen
        default:
            return controller.presentedViewController
        }
    }
}
...