В моем iOS-приложении SwiftUI у меня есть простой список объектов Item, где, проведя пальцем по строке, я могу изменить приоритет элемента и, таким образом, изменить его положение в списке. Однако при этом анимация становится очень прерывистой:
https://youtube.com/shorts/aVP-V-vf10E
Если я добавлю .id(UUID()) в список, это устранит проблему, но это не кажется хорошим решением. Почему мне нужно постоянно обновлять данные, если Item доступен для наблюдения? Может ли кто-нибудь объяснить мне, почему это происходит и как это лучше исправить?
Полный код указан ниже:
import Foundation
import SwiftData
@Model
final class Item
{
var id: UUID = UUID()
var text: String = ""
var priority: Int = 0
init(text: String)
{
self.text = text
}
}
struct ContentView: View
{
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
var body: some View
{
List
{
Section
{
ItemList(filteredAndSortedItems: filteredAndSortedItems())
}
}
.id(UUID())
.onAppear
{
seedItemsIfNeeded()
}
}
private func filteredAndSortedItems() -> [Item]
{
self.items.sorted
{
$0.priority > $1.priority
}
}
private func seedItemsIfNeeded()
{
for item in items
{
modelContext.delete(item)
}
let dummyItems =
[
Item(text: "First item"),
Item(text: "Second item"),
Item(text: "Third item"),
Item(text: "Fourth item")
]
for item in dummyItems
{
modelContext.insert(item)
}
}
}
struct ItemList: View
{
var filteredAndSortedItems: [Item]
var body: some View
{
ForEach(self.filteredAndSortedItems)
{
item in
Text("\(item.text) (Priority: \(item.priority))").swipeActions(edge: .trailing)
{
Menu
{
ForEach(0...10, id: \.self)
{
value in
Button
{
withTransaction(Transaction(animation: .none))
{
item.priority = value
}
}
label:
{
if item.priority == value
{
Label("\(value)", systemImage: "checkmark")
}
else
{
Text("\(value)")
}
}
}
}
label:
{
Image(systemName: "number")
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... s-position