Стиль презентации 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) это происходит неправильно, но, как ни странно, переключается на презентацию всплывающего окна (как в книжной, так и в альбомной ориентации), если я поворачиваю устройство после появления всплывающего окна. (Если я отклоняю поповер и снова поднимаю его, он снова будет неправильным, пока я не поверну устройство.) Кроме того, в альбомной ориентации он появляется в странной конфигурации (не в полноэкранном режиме, как на портрете):
В отличие от презентации поповера, это не отменяет, если я нажимаю вне самого представления поповера.
Документация 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 Довольно простой новый интерфейс для всплывающих окон и настраиваемых листов. Показывает, как выполнять немодальное взаимодействие с всплывающим окном и представлением за ним.