Currently building a chat application and I need new messages to appear at the bottom of the screen. I also need to have messages aligned to the bottom. However, using VStack inside ScrollView features top alignment by default.
ScrollView {
VStack(alignment: .leading, spacing: 16) {
Spacer()
.frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
ForEach(notList, id: \.self) { not in
NotRow(not: not)
}
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity, minHeight:0, alignment: Alignment.topLeading)
}
What should I do to fix this?
A bit late to answer that one but it might help someone else. You could use a good old double rotation trick to achieve the result you want. Other solutions does not work because the maximum size inside a scroll view is undefined as it depends on its child views to compute its own content size.
ScrollView {
VStack(alignment: .leading, spacing: 16) {
Spacer()
.frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
ForEach(notList, id: \.self) { not in
NotRow(not: not)
}
}
.padding()
.rotationEffect(Angle(degrees: 180))
}
.rotationEffect(Angle(degrees: 180))
ScrollView
does not propose the same height to its children (VStack
in this case) as it was proposed to it. It just asks for minimal size. The solution is to make its direct child respond with the minimum height which was proposed to ScrollView
itself. We can achieve this by reading the proposed height via GeometryReader
and setting that as minimum height of the child.
GeometryReader { reader in
ScrollView {
VStack {
/// Spacer() or Color.red will now behave as expected
}
.frame(minHeight: reader.size.height)
}
}
I think you're missing a maxHeight in VStack
VStack(alignment: .leading) {
Spacer().frame(maxWidth: .infinity)
// content here
}
.frame(maxHeight: .infinity) // <- this
If you remove Spacer()
and put it after the closing braces of your ForEach
, it will fix it. Here is how your updated code will look like:
ScrollView {
VStack(alignment: .leading, spacing: 16) {
.frame(minWidth: 0, maxWidth: .infinity, minHeight:0, maxHeight: .infinity, alignment: Alignment.topLeading)
ForEach(notList, id: \.self) { not in
NotRow(not: not)
}
Spacer()
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity, minHeight:0, alignment: Alignment.topLeading)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With