Cannot properly attach view to the bottom
Closed this issue · 2 comments
Hi,
I just started out using PinLayout and encountered problem with attachment of view to the bottom using bottom()
.
This example https://github.com/layoutBox/PinLayout/blob/master/Example/PinLayoutSample/UI/Examples/Form/FormView.swift works great when formContainer is attached to the top in this line formContainerView.pin.top().hCenter().width(100%).maxWidth(400).pinEdges().margin(margin)
.
If I modify it to formContainerView.pin.bottom().hCenter().width(100%).maxWidth(400).pinEdges().margin(margin)
I see the following result (it's completely out of visible view at first, but after next layoutSubviews
call it's partly visible but not pinned to the bottom):
I've encountered similar behaviour in my app when using wrapContent
to size parent view. It works without problems when attaching simple view to the bottom with predefined size. Any help appreciated.
Got it working by replacing formScrollView
with regular UIView and pinning formContainerView
to the bottom on the last line of layout method. Final result looks like this:
private func layoutFormFields() {
let margin: CGFloat = 12
wrapperView.pin.all(pin.safeArea)
// Layout the formContainerView using the view's safeArea.
formContainerView.pin.hCenter().width(100%).maxWidth(400).pinEdges().margin(margin)
formTitleLabel.pin.topCenter(margin)
nameField.pin.below(of: formTitleLabel).horizontally().height(40).margin(margin)
ageSwitch.pin.below(of: nameField, aligned: .left).marginTop(margin).sizeToFit()
ageField.pin.below(of: ageSwitch).horizontally().height(40).margin(margin)
// Layout the Address UITextField below the last visible view, either ageSwitch or ageField.
addressField.pin.below(of: visible([ageSwitch, ageField])).horizontally().height(40).margin(margin)
// Adjust the form container bottom to contains all its childrens
formContainerView.pin.wrapContent(.vertically, padding: margin).bottom()
}
I still don't know why previous example didn't behave like this because I don't see any reference in documentation that order of methods matter.
PinLayout layout views immediately after each line that begins with .pin
.
For:
formContainerView.pin.bottom().hCenter().width(100%).maxWidth(400).pinEdges().margin(margin)
PinLayout will layout the formContainerView
at the bottom of its parent, but since the command doesn't specify any height (or the view doesn't already have an height yet), the view will be positioned completely at the bottom, considering its height is probably still 0.
You need first to specify an height to the view before calling pin.bottom()
. In fact, this is what formContainerView.pin.wrapContent(.vertically, padding: margin)
does.
So yes, the order on which view's layout is done is important. This completely replaces the system of priority of Autolayout. You are in total control of how and when view's frame is modified.