Is it possible to limit/fix (min/max) popover size on Mac Catalyst? See the attached video.
Yes, but it's a bit of a hack. Big Sur is loading these presented view controllers as their own windows, so we can grab the window's windowScene
and set its sizeRestrictions
. The best (?) place to do this is in the presented view controller's viewWillLayoutSubviews
method:
class MyPresentedViewController: UIViewController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if #available(macCatalyst 14, *) {
view.window?.windowScene?.sizeRestrictions?.minimumSize = CGSize(width: 500, height: 500)
view.window?.windowScene?.sizeRestrictions?.maximumSize = CGSize(width: 800, height: 800)
}
}
}
If you don’t want the presented view to be resizable at all, just set the minimumSize
and maximumSize
to the same value.
I don't love using viewWillLayoutSubviews
like this, but the windowScene
is still nil in viewDidLoad
and viewWillAppear
, and while it is non-nil in viewDidAppear, setting sizeRestrictions
there will cause a visible resize on screen.
The good news is that this problem may be fixed in Big Sur 11.1. According to the beta release notes, macOS 11.1 will respect preferredContentSize
and they won't be resizable by default:
When you present a view controller with page sheet or form sheet presentation style, the size of the view controller’s root view is, by default, determined by the value returned from the presented view controller’s preferredContentSize method and the view is not resizable. You can arrange for the presented view controller to be resizable by using Auto Layout to specify the maximum and minimum sizes of its root view. To enable this, set the canResizeToFitContent property of the application’s main window to YES. One way to do this is to override the willMove(toWindow:) or didMoveToWindow() methods of a view in the main view controller. (65254666)