Загрузите больше функциональности, используя SwiftUI
Я использовал ScrollView с HStack, теперь мне нужно загрузить больше данных, когда пользователь наконец достиг прокрутки.
var items: [Landmark]
Я использовал множество предметов, которые я добавляю в HStack
с помощью ForEach
ScrollView(showsHorizontalIndicator: false) {
HStack(alignment: .top, spacing: 0) {
ForEach(self.items) { landmark in
CategoryItem(landmark: landmark)
}
}
}
Каково наилучшее из возможных решений для управления большей загрузкой в SwiftUI без использования пользовательских действий, таких как кнопка loadmore.
2 ответа
Для этого лучше использовать ForEach и List
struct ContentView : View {
@State var textfieldText: String = "String "
private let chunkSize = 10
@State var range: Range<Int> = 0..<1
var body: some View {
List {
ForEach(range) { number in
Text("\(self.textfieldText) \(number)")
}
Button(action: loadMore) {
Text("Load more")
}
}
}
func loadMore() {
print("Load more...")
self.range = 0..<self.range.upperBound + self.chunkSize
}
}
В этом примере каждый раз, когда вы нажимаете load, это увеличивает диапазон свойств State. То же самое вы можете сделать для BindableObject. Если вы хотите сделать это автоматически, вероятно, вам следует прочитать о PullDownButton(я не уверен, работает ли он для PullUp)
UPD: в качестве опции вы можете загружать новые элементы, используя модификатор onAppear в последней ячейке (в данном примере это статическая кнопка)
var body: some View {
List {
ForEach(range) { number in
Text("\(self.textfieldText) \(number)")
}
Button(action: loadMore) {
Text("")
}
.onAppear {
DispatchQueue.global(qos: .background).asyncAfter(deadline: DispatchTime(uptimeNanoseconds: 10)) {
self.loadMore()
}
}
}
}
Имейте в виду, что отправка необходима, потому что без нее у вас будет ошибка "Обновление табличного представления при обновлении табличного представления). Возможно, вы можете использовать другой асинхронный способ обновления данных.
Если вы хотите продолжать использовать List сData
вместоRange
, вы можете реализовать следующий скрипт:
struct ContentView: View {
@State var items: [Landmark]
var body: some View {
List {
ForEach(self.items) { landmark in
CategoryItem(landmark: landmark)
.onAppear {
checkForMore(landmark)
}
}
}
}
func checkForMore(_ item: LandMark) {
guard let item = item else { return }
let thresholdIndex = items.index(items.endIndex, offsetBy: -5)
if items.firstIndex(where: { $0.id == item.id }) == thresholdIndex {
// function to request more data
getMoreLandMarks()
}
}
}
Вероятно, вам следует работать в ViewModel и отделить логику от пользовательского интерфейса.
Кредиты Донни Уолсу: полный пример