Я использую NavigationView, чтобы представить список элементов с целевым представлением, чтобы показать детали элемента. Я хочу, чтобы подробное представление отображалось только при выборе элемента списка. Следующий код демонстрирует проблему:
import SwiftUI
/*
Model
*/
struct Item: Identifiable, Hashable {
let id = UUID()
let date: Date
let name: String
}
/*
List view
*/
struct ContentView: View {
@State var itemArray: [Item] = [
Item(date: Date(), name: "Item 1"),
Item(date: Date(), name: "Item 2"),
Item(date: Date(), name: "Item 3")
]
@State var selectedItem: Item?
var body: some View {
VStack {
NavigationView {
List {
ForEach(itemArray, id: \.self) { item in
NavigationLink(
destination: DetailView(item: item),
tag: item,
selection: $selectedItem
) {
Text("\(item.name)").font(.headline)
}
.contextMenu {
Button("Delete", action: {
delete(item)
//selectedItem = nil
//DispatchQueue.main.asyncAfter(deadline: .now() + 1) { delete(item) }
})
}
}
.onDelete() { offsets in
itemArray.remove(atOffsets: offsets)
//selectedItem = nil
//DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { itemStore.delete(offsets: offsets) }
}
}
// Uncommenting this provides a placeholder for the detail view but prevents onDelete on macOS
//Text("Select item...")
}
Text(selectedItem?.name ?? "No selection")
}
}
private func delete(_ item: Item) {
var index: Int? = nil
for i in 0..<itemArray.count {
if item == itemArray[i] { index = i }
}
if index != nil { itemArray.remove(at: index!) }
}
}
/*
Detail view
*/
struct DetailView: View {
var item: Item
var body: some View {
Text(item.name)
}
}
Проблема возникает, когда элемент в списке удаляется, и есть два шаблона странного поведения в зависимости от того, присутствует ли заполнитель или нет:
Без заполнителя: (текст комментария (выберите элемент ...)):
Действие: выберите элемент 1 и удалите его (проведя пальцем по экрану или используя контекстное меню)
Результат: Ожидаемое поведение: подробное представление пусто. Фактическое поведение: подробный вид для элемента 1 все еще присутствует
С заполнителем:
Возникает ожидаемое поведение, но НЕ для последнего элемента в списке
Попытки обойти:
- Явно установить для выбора значение nil перед удалением - не удается
- Используйте индексы, как предложено здесь - не удается
- Обходной путь 1 с задержкой перед удалением - работает, но это взлом
Я тестировал это на macOS BigSur 11.2.3 и iPadOS 14.4.1 (в альбомной ориентации), и проблема одинакова для обеих платформ.
Мои вопросы:
- Это ошибка или я что-то упускаю?
- Есть ли надежный обходной путь?
- Как сделать так, чтобы удаление смахивания отображалось в macOS при наличии заполнителя?