Reputation: 370
I have an app whose main view controller (call it VC-A) is locked in portrait orientation. I would like to present a sheet-style modal (call it VC-B) over top of it, allowing the modal to rotate freely. There are some additional constraints:
There have been many similar questions and responses over the years, but most of the suggested answers don't meet all of these requirements, don't work with modal presentation, or are much too hacky. That said, this should definitely be possible – I have seen at least two apps with implementations that meet my requirements. Not sure if it's kosher to post existing apps here, but I can provide examples if needed.
So far, I have tried the following:
UINavigationController
subclassSomething similar to the answer here, where the containing navigation controller returns a different value for supportedInterfaceOrientations
depending on the topmost controller. This works but violates (1) and (2) – there is always an animation when presenting or dismissing a view controller that requires a different orientation than the previous one.
I also tried presenting the modal from a transparent nested/child view controller, but that has similar limitations.
UIWindows
(more promising)Instead of presenting VC-B directly from VC-A (or a common parent), create a new, transparent UIWindow
and use its rootViewController
to present the modal. This solves (1) and (2) beautifully:
However, it fails at (3) because the sheetPresentationController
no longer involves VC-A. Instead, the clear rootViewController
is animated, resulting in a transparent shadow on top of VC-A:
This shadow/dimming can be prevented by setting largestUndimmedDetentIdentifier
to .large
:
However, I just want to apply that effect to VC-A, not eliminate it entirely. The end result should look just like it does when no separate UIWindow
is involved:
I can think of some potential workarounds, but I'm not really sure how to proceed. I have tried presenting a transparent view controller (call it VC-C) from VC-A at the same time as presenting VC-B from the other UIWindow
. This creates the illusion that VC-B is being presented from the same view hierarchy as VC-A (by causing VC-A to have the push down effect I want), but complicates dismissal. It's trivial enough to ensure that both sheets are dismissed at the same time if dismiss()
is used directly, but if the user drags down on VC-B, it seems quite difficult to get VC-C to sync with that motion.
Is there some other technique or API I'm missing? Maybe some mystery configuration of UISheetPresentationController
that I've overlooked, or a clever way to use custom transitions? Some way to mirror the contents of VC-A into the other window's rootViewController
? Again, this should be very possible as I have seen it happen in the wild.
Upvotes: 0
Views: 65