Margins work properly for the UIKit implementation of embeds, but not SwiftUI, React Native, and Flutter. Why? Each of the broken options wrap the AppcuesFrameView in a UIViewController and set the content size according to the preferredContentSize of that UIViewController.
The margins on an embed were being set by way of constant values on constraints. The AppcuesFrameView had a child view that constrained to be inset by the margins. The issue is that the preferredContentSize that gets reported up the view controller chain doesn't include these margin values which are outside the frame of the UIViewController.view.
So for example, if the preferredContentSize is 300x150 and there's 10px margins, the total frame size should be 320x170, but instead the margins were getting applied inside the 300x150 box, resulting in 280x130 for content, and thus a scrollbar (note the scrollbar on the broken image below).
The solution is to use the directionalLayoutMargins of the AppcuesFrameView which is a property that can then be read by the wrapping UIViewController and added to preferredContentSize to get the final content size.
Fixed
Broken
Notes
Unfortunately the changes to AppcuesFrame.swift will need to be made to the React Native and Flutter implementations. I looked long and hard for a solution that could be self contained, but that would require wrapping every frame in another UIViewController just to do the logic.
viewRespectsSystemMinimumLayoutMargins is necessary because otherwise I was getting non-zero horizontal margins when none were specified. I initially thought to add this to the AppcuesFrameView just before viewController.embedChildViewController(...), but for the UIKit case where viewController is actually the VC in the customers app and not an VC created by the SDK, that could potentially cause layout issues.
Margins work properly for the UIKit implementation of embeds, but not SwiftUI, React Native, and Flutter. Why? Each of the broken options wrap the
AppcuesFrameView
in aUIViewController
and set the content size according to thepreferredContentSize
of thatUIViewController
.The margins on an embed were being set by way of
constant
values on constraints. TheAppcuesFrameView
had a child view that constrained to be inset by the margins. The issue is that thepreferredContentSize
that gets reported up the view controller chain doesn't include these margin values which are outside the frame of theUIViewController.view
.So for example, if the preferredContentSize is 300x150 and there's 10px margins, the total frame size should be 320x170, but instead the margins were getting applied inside the 300x150 box, resulting in 280x130 for content, and thus a scrollbar (note the scrollbar on the broken image below).
The solution is to use the
directionalLayoutMargins
of theAppcuesFrameView
which is a property that can then be read by the wrappingUIViewController
and added topreferredContentSize
to get the final content size.Notes
UIViewController
just to do the logic.viewRespectsSystemMinimumLayoutMargins
is necessary because otherwise I was getting non-zero horizontal margins when none were specified. I initially thought to add this to theAppcuesFrameView
just beforeviewController.embedChildViewController(...)
, but for the UIKit case whereviewController
is actually the VC in the customers app and not an VC created by the SDK, that could potentially cause layout issues.