Last active
July 2, 2024 09:51
-
-
Save benigumocom/cb28d9a59336e1d585d6ac736c42fc1d to your computer and use it in GitHub Desktop.
【SwiftUI】ScrollView + LazyVStack vs Large amounts of data 👉 https://android.benigumo.com/20240627/scrollview-lazyvstack-vs-large-amounts-of-data/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import SwiftData | |
@MainActor @Observable | |
final class LargeData { | |
var loadedItems: [Item] = [] | |
var count = 0 | |
private var modelContext: ModelContext! | |
private var predicate: Predicate<Item>! | |
private var page = 0 | |
private let limit = 1000 | |
func setContext(modelContext: ModelContext) { | |
self.modelContext = modelContext | |
} | |
func find(contains: String) { | |
predicate = .predicateItems(text: contains) | |
count = ( | |
try? modelContext.fetchCount(.fetchItems(predicate: predicate)) | |
) ?? 0 | |
page = 0 | |
loadedItems.removeAll() | |
fetchPage() | |
} | |
func next() { | |
if count > (page + 1) * limit { | |
page += 1 | |
fetchPage() | |
} | |
} | |
private func fetchPage() { | |
loadedItems.append( | |
contentsOf: ( | |
try? modelContext.fetch( | |
.fetchItems(predicate: predicate, offset: page * limit, limit: limit) | |
) | |
) ?? [] | |
) | |
} | |
} | |
fileprivate extension Predicate { | |
static func predicateItems(text: String) -> Predicate<Item> { | |
return #Predicate { text.isEmpty || $0.s.contains(text) } | |
} | |
} | |
fileprivate extension FetchDescriptor { | |
static func fetchItems( | |
predicate: Predicate<Item>, offset: Int = 0, limit: Int? = nil) -> FetchDescriptor<Item> { | |
var descriptor = FetchDescriptor<Item>(predicate: predicate, sortBy: [.init(\.i)]) | |
descriptor.fetchOffset = offset | |
descriptor.fetchLimit = limit | |
return descriptor | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment