When I add a UIHostingController which contains a SwiftUI view as a childView, and then place that childView inside a UIScrollView, scrolling breaks.
Here I have my View
struct TestHeightView: View {
let color: UIColor
var body: some View {
VStack {
Text("THIS IS MY TEST")
.frame(height: 90)
}
.fixedSize(horizontal: false, vertical: true)
.background(Color(color))
.edgesIgnoringSafeArea(.all)
}
}
Then I have a UIViewController with a UIScrollView as the subView. Inside the UIScrollView there is a UIStackView that is correctly setup to allow loading UIViews and scrolling through them if the stack height becomes great enough. This works. If I were to load in 40 UILabels, it would scroll through them perfectly.
The problem arises when I add a plain old UIView, and then add a UIHostingController inside that container. I do so like this:
let container = UIView()
container.backgroundColor = color.0
stackView.insertArrangedSubview(container, at: 0)
let test = TestHeightView(color: color.1)
let vc = UIHostingController(rootView: test)
vc.view.backgroundColor = .clear
add(child: vc, in: container)
func add(child: UIViewController, in container: UIView) {
addChild(child)
container.addSubview(child.view)
child.view.translatesAutoresizingMaskIntoConstraints = false
child.view.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true
child.view.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: 0).isActive = true
child.view.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
child.view.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: 0).isActive = true
child.didMove(toParent: self)
}
In my example I added 3 of these containerViews/UIHostingController and then one UIView (green) to demonstrate what is happening.
You can see that as I scroll, all views are suspended as a gap is formed. What is happening is that the containing UIView (light color) is expanding its height. Once the height reaches a certain value, scrolling continues as normal until the next container/UIHostingController reaches the top and it begins again.
I have worked on several different solutions .edgesIgnoringSafeArea(.all)
Does do something. I included it in my example because without it, the problem is exactly the same only more jarring and harder to explain using a video. Basically the same thing happens but without any animation, it just appears that the UIScrollView has stopped working, and then it works again
Edit:
I added another UIViewController just to make sure it wasn't children in general causing the issue. Nope. Only UIHostingControllers do this. Something in SwiftUI