Reputation: 1064
For populating ScrollView with a large amount of data, apple is suggesting using LazyVGrid inside the ScrollView: LazyVGrid - Apple
So this sample code that is loading 500 random photos works perfectly in case of memory management: (Almost 30MB).
I used KingFisher as image loader.
var body: some View {
ScrollView {
LazyVGrid(columns: [GridItem(.flexible())]) {
ForEach(1...500, id: \.self) { value in
KFImage(URL(string: "https://picsum.photos/800/800?\(value)"))
}
}
}
}
But I want to have a controll over the content of ScrollView, like offset.
So as soon as I added .content.offset(y: 5)
the memory goes up to 640MB !!
var body: some View {
ScrollView {
LazyVGrid(columns: [GridItem(.flexible())]) {
ForEach(1...500, id: \.self) { value in
KFImage(URL(string: "https://picsum.photos/800/800?\(value)"))
}
}
}
.content.offset(y: 5)
}
Is there any reason behind the .content
?!! How can I handle not having a large amount of memory?
I need to disable scroll and control content offset manually, not by using ScrollViewReader
.
Thanks
Upvotes: 0
Views: 632
Reputation: 54745
You shouldn't be accessing the content
of a ScrollView
outside a ScrollView
. If you want to modify the content, simply add the modifications to the body of the ScrollView
.
If you are accessing content
outside the ScrollView
, SwiftUI has to calculate content
2x - once inside the content
closure of the ScrollView
and again when accessed from outside the ScrollView
. This also breaks the lazy-loading of lazy grids as stacks, since the layout system cannot detect what parts of the view are currently visible, so it has to load the whole view into memory.
var body: some View {
ScrollView {
LazyVGrid(columns: [GridItem(.flexible())]) {
ForEach(1...500, id: \.self) { value in
KFImage(URL(string: "https://picsum.photos/800/800?\(value)"))
}
}
.offset(y: 5)
}
}
Upvotes: 3