According to documentation,
In a horizontally compact environment, popovers adapt to the UIModalPresentationOverFullScreen presentation style by default.
See below image. In compact environment, popover appear from bottom and animate to top until it covers the entire screen.
Is it possible to override this behaviour and have the popover only covering certain height of the screen as shown below?
Following code demonstrate the default behaviour of popover adapting to FullScreen presentation style in compact environment.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .systemBackground
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setImage(UIImage(systemName: "square.grid.2x2.fill"), for: .normal)
button.addTarget(self, action: #selector(displayPopover), for: .touchUpInside)
self.view.addSubview(button)
NSLayoutConstraint.activate([
button.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100),
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
button.widthAnchor.constraint(equalToConstant: 40),
button.heightAnchor.constraint(equalToConstant: 40),
])
}
@IBAction func displayPopover(sender: UIButton!) {
let popoverVC = PopoverViewController()
popoverVC.preferredContentSize = CGSize(width: 300, height: 200)
popoverVC.modalPresentationStyle = .popover
popoverVC.popoverPresentationController?.sourceView = sender
popoverVC.popoverPresentationController?.permittedArrowDirections = .up
self.present(popoverVC, animated: true, completion: nil)
}
}
class PopoverViewController: UIViewController {
override func viewDidLoad() {
self.view.backgroundColor = .systemGray
}
}
Output:
This feature is now available with iOS 15.
Watch WWDC2021 short video
Download WWDC sample project from here
@IBAction func showImagePicker(_ sender: UIBarButtonItem) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.modalPresentationStyle = .popover
if let popover = imagePicker.popoverPresentationController {
popover.barButtonItem = sender
let sheet = popover.adaptiveSheetPresentationController
sheet.detents = [.medium(), .large()]
sheet.largestUndimmedDetentIdentifier = .medium
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
sheet.prefersEdgeAttachedInCompactHeight = true
sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
}
present(imagePicker, animated: true, completion: nil)
}