I would like to add dynamically View Controllers inside a UIStackView
.
The UIStackView
must be scrollable so I added it inside a UIScrollView
.
I have an UI error, the content size is ambiguous, I tried to debug using Debug View Hierarchy
and here it's the result :
Sizes of each controller inside the UIStackView
is .zero
--
Here is my hierarchy on the StoryBoard
The constraints :
ScrollView
.leading
=StackView
.leading
ScrollView
.trailing
=StackView
.trailing
ScrollView
.top
=StackView
.top
ScrollView
.bottom
=StackView
.bottom
ScrollView
.width
=StackView
.width
ScrollView
.height
=StackView
.height
My source code :
class ScrollViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var stackView: UIStackView!
private var strings = ["echo", "hola", "allo"]
private var containerViews = [ContainerView]()
override func viewDidLoad() {
super.viewDidLoad()
self.setupViews()
}
private func setupViews() {
self.setupContainers()
}
fileprivate func removeContainers() {
for container in containerViews {
container.uninstall()
}
containerViews.removeAll()
}
fileprivate func setupContainers() {
removeContainers()
for string in strings {
let viewController = // get the view Controller from StoryBoard
add(viewController)
}
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let viewController = segue.destination
let index = strings.index(of: sender as! String)!
}
fileprivate func add(_ viewController: UIViewController) {
let containerView = ContainerView(parentController: self)
containerView.install(viewController)
stackView.addArrangedSubview(containerView)
}
}
class ContainerView<T:UIViewController>: UIView {
unowned var parentViewController: UIViewController
weak var currentController: T?
init(parentController: UIViewController) {
self.parentViewController = parentController
super.init(frame: CGRect.zero)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func install(_ viewController: T) {
pushViewController(viewController, animated: false)
}
func uninstall() {
if let controller = currentController {
removeViewController(controller)
currentController = nil
}
}
fileprivate func setUpViewController(_ targetViewController: T?, animated: Bool) {
if let viewController = targetViewController {
parentViewController.addChildViewController(viewController)
viewController.view.frame = self.bounds
self.addSubview(viewController.view)
viewController.didMove(toParentViewController: parentViewController)
}
}
fileprivate func removeViewController(_ viewController: T?) {
if let _viewController = currentController {
_viewController.willMove(toParentViewController: nil)
_viewController.view.removeFromSuperview()
_viewController.removeFromParentViewController()
}
}
fileprivate func pushViewController(_ controller: T, animated: Bool) {
removeViewController(currentController)
currentController = controller
setUpViewController(controller, animated: false)
}
}
I cannot scroll on the UIScrollView
because the content size is not set correctly. Anyone know how to resolve this bug ?
EDIT: You can see here the git with an example of the bug : GitHub StackViewOnScrollView