Мне удалось получить хорошую вставку и удаление анимации для элементов, отображаемых в ForEach
(выполняется через .transition(...)
на Row
). Но, к сожалению, эта анимация также запускается, когда я просто обновляю имя Item
в наблюдаемом массиве. Конечно, это потому, что на самом деле это новое представление (вы можете видеть это, поскольку вызывается onAppear()
из Row
).
Как мы все знаем, рекомендуемый способ управления списками с классной анимацией будет List
но я думаю, что многие люди хотели бы избежать стандартного пользовательского интерфейса или ограничений, сопровождающих этот элемент.
Прилагается рабочий пример SwiftUI , пример (Сборка с Xcode 11.4 )
Итак, вопрос:
Есть ли умный способ подавить анимацию (или иметь другую) для только что обновленных элементов, которые будут сохранять ту же позицию? Есть ли классная возможность «повторно использовать» строку и просто обновить ее?
Или ответ «Давайте подождем следующую WWD C и посмотрим, исправит ли ее Apple ... "? ; -)
Приветствия,
Орландо ?
Редактировать
Бонки Фронкс ответ на самом деле хороший подход, когда вы можете различить guish между редактированием / добавлением / удалением (например, ручными действиями пользователя). Как только массив items
обновляется в фоновом режиме (например, с помощью синхронизированных обновлений, поступающих из Core Data в вашей модели представления), вы не знаете, является ли это обновлением или нет. Но, возможно, в этом случае ответ будет заключаться в том, чтобы вручную реализовать случаи вставки / обновления / удаления в модели представления.
struct ContentView: View {
@State var items: [Item] = [
Item(name: "Tim"),
Item(name: "Steve"),
Item(name: "Bill")
]
var body: some View {
NavigationView {
ScrollView {
VStack {
ForEach(items, id: \.self) { item in
Row(name: item.name)
}
}
}
.navigationBarItems(leading: AddButton, trailing: RenameButton)
}
}
private var AddButton: some View {
Button(action: {
self.items.insert(Item(name: "Jeff"), at: 0)
}) {
Text("Add")
}
}
private var RenameButton: some View {
Button(action: {
self.items[0].name = "Craigh"
}) {
Text("Rename first")
}
}
}
struct Row: View {
@State var name: String
var body: some View {
HStack {
Text(name)
Spacer()
}
.padding()
.animation(.spring())
.transition(.move(edge: .leading))
}
}
struct Item: Identifiable, Hashable {
let id: UUID
var name: String
init(id: UUID = UUID(), name: String) {
self.id = id
self.name = name
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}