-
-
Notifications
You must be signed in to change notification settings - Fork 10
Question: Is automatic height for children supported? #172
Comments
@zocario hey mate, you should be able to use view controllers that use auto layout, |
@zocario Is this what you want to achieve? I modified the class HeaderViewController: UIViewController {
let containerView = UIView()
let subview = UIView()
override func viewDidLoad() {
super.viewDidLoad()
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.backgroundColor = .gray
subview.backgroundColor = .red
subview.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(subview)
subview.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
subview.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
subview.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
#warning("This constraints is removed as impossible to statisfies")
subview.heightAnchor.constraint(equalToConstant: 200).isActive = true
self.view.addSubview(containerView)
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
containerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.frame.size.height = subview.frame.size.height
}
} |
@zocario here is another example if you want to toggle the height by tapping on the view. class HeaderViewController: UIViewController {
let containerView = UIView()
let subview = UIView()
var heightConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.backgroundColor = .gray
subview.backgroundColor = .red
subview.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(subview)
subview.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
subview.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
subview.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
heightConstraint = subview.heightAnchor.constraint(equalToConstant: 200)
#warning("This constraints is removed as impossible to statisfies")
heightConstraint?.isActive = true
self.view.addSubview(containerView)
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
containerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle))
subview.addGestureRecognizer(tapGesture)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.frame.size.height = subview.frame.size.height
}
@objc func toggle() {
if heightConstraint?.constant == 200 {
heightConstraint?.constant = 100
} else {
heightConstraint?.constant = 200
}
UIView.animate(withDuration: 0.25, delay: 0.0, options: [.beginFromCurrentState, .allowUserInteraction], animations: {
self.view.layoutIfNeeded()
self.view.frame.size.height = self.subview.frame.size.height
}, completion: nil)
}
} |
And to answer your original question, the current outline that you presented is probably a better fit to implement as a The pros with doing child view controller is that you decouple yourself from a reuse/dequeing scheme. You can basically feed it your view models directly and guarantee that you have an instance of something instead of going through the hoops of using the delegate, reload, cell for item at index paths methods etc. I'd roll with doing the basics and when you need more, you simply refactor it using something that can fulfill those requirements. Hope that helps! Feel free to followup if you have anything else that you are wondering about :) |
Hello @zenangst thanks for your detailed answer that was really fast! I'll give it an other try regarding your answers and maybe re-consider using the table view header :) The footer isn't scrolling with the tableview that's why I thought about this three view controllers setup. |
Should you be able to set the footer as sticky if you want it to follow the scrolling? There are multiple ways to skin a cat :) |
Yes effectively there is a lots of possible ways, maybe too much :) I did a second version of my test that is a little bit closer to our view implementation, which uses a vertical stack view with labels, images. In that case I'm still facing a problem with the height of my header. To be honest I'm not sure to understand why I need to set the height of my view in Updated version of my sample with a vertical stack view: Thanks! |
@zocario I'll have a second look at this when life allows but basically, the view of a view controller is not automatically self-sizing. Hence you having to change the size of that view for it to work, to get rid of having to set a manual size of your child view controller, you could use a custom view as the view controllers view by implementing But like I said, I'm gonna look at your example when life allows and get back to you with more details. |
@zocario the easiest way to make a self-sizing view controller is to switch out the view of the view controller, then you don't need the Note that this is not something that is unique for If you take a look at this example: class HeaderViewController: UIViewController {
let customView = UIStackView()
override func loadView() {
self.view = customView
}
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel()
label.numberOfLines = 0
label.textColor = .white
label.text = "SALU TAOJ EAOJ \naAK LK ALZK F\nAOK ZOAK F"
let label2 = UILabel()
label2.textColor = .red
label2.numberOfLines = 0
label2.text = "SALU TAOJ EAOJ \naAK LK ALZK F\nAOK ZOAK F"
customView.addArrangedSubview(label)
customView.addArrangedSubview(label2)
customView.axis = .vertical
customView.backgroundColor = .red
customView.translatesAutoresizingMaskIntoConstraints = false
}
} It will render something like this: I hope this helps! |
Hey @zocario did you manage to get anywhere with this? |
ping @zocario |
Hello @zenangst I'm really sorry I disabled email notifications and missed your last comments 🙈 For this specific view I finally used a table view as it was making more sense. But it looks like you're right assigning the view in |
I mark the issue as solved 🙏 |
@zocario no worries mate, cheers! 😎 |
Hello and thanks for this library :)
We're trying to take advantage of child view controllers to split a view controller that is now really too complex. Here is how we want to organize it after refactoring (at the moment this is one UITableViewController subclass):
I've just started to play with your library and I encountered a problem : our header has a dynamic height, which is set automatically with auto layout constraints. I've succeed to set fixed height for this container using the
height
parameter ofaddChild
but with only auto layout constraints I couldn't. Also I encountered a case where I could scroll in the tableview and the main scroll view wasn't scrolling..So I would like to know if this is supported to have height set using auto layout? Regarding #73 I have the feeling it's not.
Regarding your experience in child view controller, is it a good pattern to split this controller in three view controllers in that way? Maybe it's just easier to use the table view header to add the header controller?
I've included a sample project to quickly show the problem I'm having.
Test family.zip
Thanks for your help!
The text was updated successfully, but these errors were encountered: