(This is a show stopper issue for me to use VStack or LazyVStack in my app. I posted the issue here on SO but got no reply. So I'll ask in this forum.)
What I'm trying to implement is a very basic behavior: I have some items in VStack and I'd like to scroll to some item when the VStack is shown. The issue is scrollTo() scrolls too much and leads to invalid UI. See diagram below.
Setup: there are 3 items in the VStack and I'd like to scroll to the last one.
+--------------+ +--------------+
| c | | a |
| | | b |
| | | c |
| | | |
| | | |
| | | |
| | | |
| | | |
+--------------+ +--------------+
(a) What I saw (b) What I expected
The UI in diagram a is invalid and misleading because 1) it's impossible for user to get such UI interactively, and 2) when user see it he would think there is only one item.
I have been investigating how to work around the issue but couldn't find one. I found two discussion that might be relevant, but both of them were about iOS 15. I don't find any discussion on a similar issue on iOS 16.
Below is the code to reproduce the issue. I filed FB12173661 yesterday. I wonder if anyone has a workaround? Thanks.
My environment: Xcode 14.2, iOS 16.3.1. I'm installing Xcode 14.3 and will verify it on iOS 16.4 soon.
struct Item: Identifiable {
var id: UUID = UUID()
var value: String
}
struct TestView: View {
var items: [Item]
var scrollTo: UUID
var body: some View {
ScrollViewReader { proxy in
ScrollView {
LazyVStack {
ForEach(items) { item in
Text(item.value)
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
proxy.scrollTo(scrollTo, anchor: .top)
}
}
}
}
}
}
struct ContentView: View {
var items: [Item] = [Item(value: "a"), Item(value: "b"), Item(value: "c")]
var body: some View {
TestView(items: items, scrollTo: items.last!.id)
.frame(maxWidth: .infinity)
}
}