I am trying to place an UIPageViewController inside a UIView with no predetermined height. What I am trying to achieve is build a responsive In-app Message that has one or more components (buttons, texts, carousels, etc) that has its height determined by its children.
The modal window works fine with all components except the UIPageViewController. The UIView resizes based on whatever components I put into it, but not when I place an UIPageViewController. It seems like there are some constraints missing.
The general hierarchy is:
UIView (centered vertically on the screen with trailing and leading margins, no height)
| UIStackView (inside this UIStackView I place any number of components I wish)
| | UILabel (example component)
| | UIButton (example component)
| | UIPageViewController (example component)
| | | UIStackView (inside this UIStackView I place any other number of components)
| | | | UILabel (example component)
| | | | UIButton (example component)
…
The following log excerpt belongs to an In-app Message with these characteristics:
UIView (centered vertically on the screen with trailing and leading margins, no height)
| UIStackView (leading and trailing anchors equal to parent, top and bottom anchors equal to children)
| | UIPageViewController (will display bellow the first slide content)
| | | UIStackView
| | | | UIImageView
| | | | UILabel
| | | | UILabel
Logs:
(lldb) po [[0x7feeb7a78e30 superview ] recursiveDescription]
<UIView: 0x7feeb76c44f0; frame = (0 0; 334 0); layer = <CALayer: 0x600002afd1c0>>
| <_UIPageViewControllerContentView: 0x7feeb7a78e30; frame = (0 0; 334 0); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x600002ae1500>>
| | <_UIQueuingScrollView: 0x7feeafbc6800; frame = (0 0; 334 0); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600002773600>; layer = <CALayer: 0x600002ae0e80>; contentOffset: {334, 0}; contentSize: {1002, 0}; adjustedContentInset: {0, -334, 0, -334}>
| | | <UIView: 0x7feeb7a79b30; frame = (0 0; 334 0); layer = <CALayer: 0x600002ae04a0>>
| | | <UIView: 0x7feeb7a79ca0; frame = (334 0; 334 0); layer = <CALayer: 0x600002ae0880>>
| | | | <UIView: 0x7feeb6f25990; frame = (0 0; 757 219.667); autoresize = W+H; layer = <CALayer: 0x600002aed700>>
| | | | | <UIStackView: 0x7feeb6fb7a10; frame = (0 0; 757 219.667); layer = <CALayer: 0x600002aed8c0>>
| | | | | | <UIImageView: 0x7feeb76ceb70; frame = (0 0; 757 131.667); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x600002aff560>>
| | | | | | <UILabel: 0x7feeb76ced40; frame = (0 141.667; 757 29.6667); text = 'This is the first slide t...'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x600000bddb30>>
| | | | | | <UILabel: 0x7feeb6fb7c60; frame = (0 181.333; 757 18.3333); text = 'This is the description f...'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x600000bca0d0>>
| | | <UIView: 0x7feeb7a79e10; frame = (668 0; 334 0); layer = <CALayer: 0x600002ae0840>>
| | <UIPageControl: 0x7feeb76cb9b0; frame = (10 -25; 314 20); autoresize = W; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x600002693180>; layer = <CALayer: 0x600002afdac0>>
| | | <_UIPageControlContentView: 0x7feeb6fb4b10; frame = (111.667 -3; 91 26); layer = <CALayer: 0x600002aed0c0>>
| | | | <_UIPageControlIndicatorContentView: 0x7feeb6fb73b0; frame = (14.3333 0; 62.6667 26); autoresize = H; layer = <CALayer: 0x600002aec080>>
| | | | | <_UIPageIndicatorView: 0x7feeb6f27570; frame = (0.166667 8.16667; 9.66667 9.66667); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 0.333333 1; layer = <CALayer: 0x600002ae5b00>>
| | | | | <_UIPageIndicatorView: 0x7feeb0809630; frame = (17.5 8.16667; 9.66667 9.66667); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 0.666667 1; layer = <CALayer: 0x600002a01000>>
| | | | | <_UIPageIndicatorView: 0x7feeb6cd34c0; frame = (35.5 8.16667; 9.66667 9.66667); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 0.666667 1; layer = <CALayer: 0x600002a01080>>
| | | | | <_UIPageIndicatorView: 0x7feeb6fc6100; frame = (53.1667 8.16667; 9.66667 9.66667); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 0.666667 1; layer = <CALayer: 0x600002ae0140>>
Here are two examples. The first is a working In-app Message with no UIPageViewController. The second is what I am trying to achieve, but as a working example on Android.
Working In-app Message without UIPageViewController Working example of carousel on Android
Based on these logs, can anyone point me in the right direction of correcting the constraints? What happens is that the views higher in the hierarchy have 0 height, though their children have not. This results in a 0 height In-app Message.
Edit
I am adding the modal view as a subview to the main view and I add the UIPageViewController to the top controller when it is present in the hierarchy:
All is done via code. I am not adding a view controller, only a subview to my main view:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
if (keyWindow != nil) {
[keyWindow addSubview:self.parentView]; // self.parentView = blackish background + vertically centered UIView (the actual modal view) + UIStackView for the components
if (hasCarousel){
UIViewController *topController = [UIApplication getPresentedViewController];
if (topController != nil)
[topController embedViewController:pageViewController inView:carouselWrapper]; // carouselWrapper = UIView containing the pageViewController that is added to the UIStackView above
}
}