Skip to content

Instantly share code, notes, and snippets.

@benigumocom
Last active July 2, 2024 09:51
Show Gist options
  • Save benigumocom/cb28d9a59336e1d585d6ac736c42fc1d to your computer and use it in GitHub Desktop.
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/
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