LeoNatan/LNPopupController

Presenting view controller from detached view controller is not supported, and may result in incorrect safe area insets and a corrupt root presentation.

iDylanK opened this issue · 6 comments

Describe the Bug
Adding a navigation controller with a ViewController as its root to the presentPopupBar causes problems with presenting new specific screens that handle view changes. For example when rotating the device.

Presenting view controller <UIAlertController: 0x10301ba00> from detached view controller <DemoPopup.LargePlayerViewController: 0x1026094e0> is not supported, and may result in incorrect safe area insets and a corrupt root presentation. Make sure <DemoPopup.LargePlayerViewController: 0x1026094e0> is in the view controller hierarchy before presenting from it. Will become a hard exception in a future release.

To Reproduce
Steps to reproduce the behavior:

  1. let nav = UINavigationController(rootViewController: largePlayerViewController)
  2. presentPopupBar(withContentViewController: nav, animated: false, completion: nil)
  3. Present a View Controller X forced in landscape from the large player view controller.
  4. Rotate the device to landscape.
  5. Close view X.

Expected Behavior
The presenting view controller should return to its original orientation.

Screenshots
https://github.com/LeoNatan/LNPopupController/assets/18072630/8e8df4b7-9b29-4fef-a1d0-525df330058d

Additional Context
DemoPopup.zip

I'm not sure what I can do about this issue, other than a full rewrite of the framework, which is out of the question. I would suggest, as a workaround, to set up a delegate pattern, and present your controllers from the popup presentation container controller, rather than the popup content controller. It's an extra step, but that should work.

Several years ago, Apple, for whatever reason, completely broke this usecase. In the framework's case, it's not as simple as just adding the popup content controller to the hierarchy, because navigation and tab bar controllers (and possibly other system controllers) don't just accept child controllers—they maintain their own child controller list, and adding ones is just brittle and breaks the system behavior (can't push/pop, new tabs get added suddenly, etc.). The other way to have a controller in the hierarchy is through presentation controllers, but that would require completely rewriting the framework to present the controllers that way; this is a very big task which I don't have time to do, and many current features of the framework would not be supported in the same way they are now.

Okay, we will do this for now. Thanks!

Related to this issue is that constraints break when the app is launched with the device in a landscape orientation (but the app is fixed in portrait). We get the following errors:

	Probably at least one of the constraints in the following list is one you don't want. 
	Try this: 
		(1) look at each constraint and try to figure out which you don't expect; 
		(2) find the code that added the unwanted constraint or constraints and fix it. 
	(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x600002132940 h=-&- v=-&- UIView:0x104812650.minX == 0   (active, names: '|':_UIVisualEffectContentView:0x104b71100 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x6000021328f0 h=-&- v=-&- H:[UIView:0x104812650]-(459)-|   (active, names: '|':_UIVisualEffectContentView:0x104b71100 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x600002135270 h=-&- v=-&- _UIVisualEffectContentView:0x104b71100.minX == 0   (active, names: '|':_LNPopupBarBackgroundEffectView:0x104812fe0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x600002135220 h=-&- v=-&- H:[_UIVisualEffectContentView:0x104b71100]-(0)-|   (active, names: '|':_LNPopupBarBackgroundEffectView:0x104812fe0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x6000021350e0 h=--& v=--& _LNPopupBarBackgroundEffectView:0x104812fe0.width == 393   (active)>"
)

Will attempt to recover by breaking constraint 
<NSAutoresizingMaskLayoutConstraint:0x6000021328f0 h=-&- v=-&- H:[UIView:0x104812650]-(459)-|   (active, names: '|':_UIVisualEffectContentView:0x104b71100 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

This can be reproduced by launching this new demo project with the simulator in landscape. After opening the large player the mini player gets corrected.

DemoPopup2.zip

Hm, the constraints issue I will take a look soon. Thanks

2.18.5

Thanks!