I would like to put a SwiftUI view into UIScrollView using UIHostingController. However my button "toggle" seems to be jumping around the view during animation, even though I'm using auto layout to constrain the view.
The following video illustrates the problem of button text jumping during aniation
struct ExpandableView: View {
@State var expanded = false
var body: some View {
VStack {
Button(action: { withAnimation {expanded.toggle() }}) {
Text("toggle")
}
if expanded {
Text("long text long text long text long text long text long text long text long text long text long text long textlong text long text long text long text long text long text long text long text long text long text long textlong text long text long text long text long text long text long text long text long text long text long text")
.font(.custom("x", fixedSize: 55))
}
}
}
}
class ViewController: UIViewController {
var scrollView: UIScrollView = {
let sv = UIScrollView()
sv.isDirectionalLockEnabled = true
return sv
}()
var contentView: UIView = {
let view = UIView()
return view
}()
let controller = UIHostingController(rootView: ExpandableView())
private var heightConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
scrollView.frame = view.frame
scrollView.contentSize = CGSize(width: view.bounds.size.width, height: view.bounds.size.height + 200)
view.addSubview(scrollView)
scrollView.addSubview(contentView)
contentView.frame = scrollView.frame
contentView.bounds = scrollView.bounds
controller.view.backgroundColor = .yellow
contentView.addSubview(controller.view)
controller.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
controller.view.topAnchor.constraint(equalTo: contentView.safeAreaLayoutGuide.topAnchor),
controller.view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSize(width: view.bounds.width, height: 100 + controller.view.intrinsicContentSize.height)
}
}
