SwiftUI: сбой NavigationSplitView со смешанными условными строками и разделами
Я сообщил об этой ошибке в Apple (FB12119791), так как почти уверен, что это не ошибка в моем коде, но публикую здесь как для потомков, так и для того, чтобы посмотреть, нашел ли кто-нибудь решение. Это также сложно описать, поэтому приложенный пример кода, вероятно, будет хорошей отправной точкой.
При условном отображении строки за пределами раздела рядом с разделом строк на боковой панели NavigationSplitView может постоянно воспроизводиться сбой приложения.
Действия по воспроизведению
- Создайте представление SwiftUI с помощью NavigationSplitView. Для боковой панели разделенного представления создайте список с элементами навигации и условно отображаемым элементом без навигации (т. е. представление, которое отображается только в том случае, если логическое значение состояния истинно).
- Перейдите к месту назначения навигационного элемента, а затем вернитесь к списку.
- Отключите значение условного состояния , чтобы скрыть условно отображаемый элемент.
- Попробуйте еще раз перейти к месту назначения навигационного элемента.
Ожидаемый результат
Представление навигации должно перейти к месту назначения выбранного навигационного элемента.
Фактический результат
Приложение (или предварительная версия Xcode) аварийно завершает работу в точке входа @main приложения.
Пример кода
import SwiftUI
fileprivate struct Item: Identifiable, Hashable {
let id = UUID()
}
fileprivate let items = (0...10).map { _ in Item() }
struct ListSelectionConditionalViewCrashExample: View {
@State var showConditionalView = true
@State var selectedItem: UUID?
var body: some View {
NavigationSplitView {
List(selection: $selectedItem) {
Section {
Label("Tap a row in the navigable rows section below", systemImage: "1.circle")
Label("Return to this screen", systemImage: "2.circle")
Label("Toggle the control below **off**", systemImage: "3.circle")
Label("Tap a row in the navigable rows section below", systemImage: "4.circle")
Label("Observe the app crash", systemImage: "exclamationmark.circle")
.foregroundStyle(.red)
Text("Note this only happens when navigable and non-navigable rows appear in separate sections")
Toggle(isOn: $showConditionalView.animation()) {
Text("Render conditional view")
}
} header: {
Text("Instructions")
}
if showConditionalView {
Text("Conditional view")
}
Section {
ForEach(items) { item in
Text(item.id.uuidString)
.tag(item.id)
}
} header: {
Text("Navigable rows")
}
}
.navigationTitle("Navigation List Crash")
} detail: {
if let selectedItem,
let item = items.first(where: { $0.id == selectedItem }) {
Text(item.id.uuidString)
.navigationTitle("Detail View")
} else {
Text("No selection")
}
}
}
}
struct ListSelectionConditionalViewCrashExample_Previews: PreviewProvider {
static var previews: some View {
ListSelectionConditionalViewCrashExample()
}
}