Стиль презентации Popover на устройствах iPhone - возможно, больше?

Я пытаюсь определить представление popover, прикрепленное к такому представлению:

желаемое появление поповера

Вот мой код:

class MyController: UIViewController, UIPopoverPresentationControllerDelegate {

    ...

    func displaySignOut(_ sender: UIButton) {
        let vc = UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "signOutPopover")
        vc.modalPresentationStyle = .popover
        vc.preferredContentSize = CGSize(width: 100, height: 30)
        present(vc, animated: true, completion: nil)

        let pc = vc.popoverPresentationController!
        pc.sourceView = sender
        pc.sourceRect = sender.bounds
        pc.delegate = self
    }

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

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

Поскольку поповер такой маленький, я бы хотел использовать этот стиль на всех устройствах. Я следовал обычному совету (например, здесь) о переопределении adaptivePresentationStyle возвращать UIModalPresentationStyle.none,

Это отлично работает на устройствах iPad, а на iPhone - нет. На небольших устройствах iPhone он отображается на весь экран. На больших экранах (например, iPhone 7 Plus) это происходит неправильно, но, как ни странно, переключается на презентацию всплывающего окна (как в книжной, так и в альбомной ориентации), если я поворачиваю устройство после появления всплывающего окна. (Если я отклоняю поповер и снова поднимаю его, он снова будет неправильным, пока я не поверну устройство.) Кроме того, в альбомной ориентации он появляется в странной конфигурации (не в полноэкранном режиме, как на портрете):

Как выглядит поповер в альбомной ориентации на iPhone 7 Plus

В отличие от презентации поповера, это не отменяет, если я нажимаю вне самого представления поповера.

Документация Apple гласит (частично):

В горизонтально компактной среде поповеры адаптируются к UIModalPresentationOverFullScreen стиль презентации по умолчанию.

"По умолчанию" настоятельно предполагает, что есть способ переопределить это поведение. Но (как это согласуется с этим постом) adaptivePresentationStyle в делегате, кажется, не способ сделать это больше (хотя раньше это работало). Так есть ли новый способ изменить поведение по умолчанию?

Я использую XCode 8.3.3 и Swift 3.1 для iOS 9+.

2 ответа

Решение

Я создал один пользовательский класс с раскадровкой внутри, который соединяет выход кнопки и реализовал код ниже.

import UIKit
class PopOverViewController: UIViewController {

    @IBOutlet weak var button: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        button.backgroundColor = UIColor.purple
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //Updating the popover size
    override var preferredContentSize: CGSize {
        get {
            let size = CGSize(width: 80, height: 60)
            return size
        }
        set {
            super.preferredContentSize = newValue
        }
    }


    //Setup the ViewController for popover presentation
    func updatePopOverViewController(_ button: UIButton?, with delegate: AnyObject?) {
        guard let button = button else { return }
        modalPresentationStyle = .popover
        popoverPresentationController?.permittedArrowDirections = [.any]
        popoverPresentationController?.backgroundColor = UIColor.purple
        popoverPresentationController?.sourceView = button
        popoverPresentationController?.sourceRect = button.bounds
        popoverPresentationController?.delegate = delegate
    }

}

И тогда внутри ViewController реализовал одну функцию, чтобы показать popOver на iphone

func showPopOver(button: UIButton!) {
 let viewController = PopOverViewController()
 viewController.updatePopOverViewController(button, with: self)
  present(viewController, animated: true, completion: nil)
}

Примечание:- Протестировано, и это должно работать и в портретном режиме.

В iOS 15 есть несколько новых способов решения этой проблемы. Взгляните на сессию WWDC21 «Настройка и изменение размера листов в UIKit» https://developer.apple.com/wwdc21/10063 Довольно простой новый интерфейс для всплывающих окон и настраиваемых листов. Показывает, как выполнять немодальное взаимодействие с всплывающим окном и представлением за ним.

Другие вопросы по тегам