SwiftUI: проблемы с строкой заголовка NavigationSplitView
Я зарегистрировал это как ошибку в Apple (FB12119822), так как я совершенно уверен, что с моим кодом все в порядке, но публикую здесь для потомков и на случай, если другие люди найдут обходной путь.
При переходе между разделами списка и разделов сведений в NavigationSplitView строка заголовка неожиданно переключается между встроенным и большим режимами отображения. В некоторых случаях заголовок кажется пустым до тех пор, пока переход навигации не будет завершен, после чего он внезапно отображается в режиме большого отображения, сдвигая содержимое представления вниз.
Действия по воспроизведению
- Создайте NavigationSplitView с боковой панелью элементов списка, по которым можно перемещаться, и подробное представление, соответствующее выбранному элементу, с заголовком панели навигации.
- Перейдите к подробному представлению
Ожидаемый результат
Переход навигации анимирует исходный заголовок в кнопке «Назад» на панели навигации и одновременно анимирует заголовок панели навигации пункта назначения в режим отображения по умолчанию (большой).
Фактический результат
Переход навигации анимирует исходный заголовок в кнопке «Назад» на панели навигации, но заголовок пункта назначения не отображается. Когда переход завершается, текст кнопки «Назад» заменяется текстом по умолчанию («Назад»), и внезапно появляется заголовок места назначения. (запись экрана)
Дополнительные наблюдения
Вышеупомянутое поведение проявляется, когда список NavigationSplitView имеетselection
аргумент. Когда вместо этогоnavigationDestination
При применении модификатора это повлияет на строку заголовка как списка источника, так и подробного представления пункта назначения. (запись экрана)
Примеры кода
List(selection:)
import SwiftUI
fileprivate struct Item: Identifiable, Hashable {
let id = UUID()
}
fileprivate let items = (0...10).map { _ in Item() }
struct ListWithSelectionTitleBarJumpExample: View {
@State var selectedItem: UUID?
var body: some View {
NavigationSplitView {
List(selection: $selectedItem) {
Section {
ForEach(items) { item in
Text(item.id.uuidString)
.tag(item.id)
}
} header: {
Text("Navigable rows")
}
}
.navigationTitle("Navigation Title Jump")
} detail: {
if let selectedItem,
let item = items.first(where: { $0.id == selectedItem }) {
Text(item.id.uuidString)
.navigationTitle("Detail View")
} else {
Text("No selection")
}
}
}
}
struct ListWithSelectionTitleBarJumpExample_Previews: PreviewProvider {
static var previews: some View {
ListWithSelectionTitleBarJumpExample()
}
}
List.navigationDestination
import SwiftUI
fileprivate struct Item: Identifiable, Hashable {
let id = UUID()
}
fileprivate let items = (0...10).map { _ in Item() }
struct ListWithNavigationDestinationTitleBarJumpExample: View {
var body: some View {
NavigationSplitView {
List {
Section {
ForEach(items) { item in
NavigationLink(value: item) {
Text(item.id.uuidString)
}
}
} header: {
Text("Navigable rows")
}
}
.navigationTitle("Navigation Title Jump")
.navigationDestination(for: Item.self) { value in
Text(value.id.uuidString)
.navigationTitle("Detail View")
}
} detail: {
Text("No selection")
}
}
}
struct ListWithNavigationDestinationTitleBarJumpExample_Previews: PreviewProvider {
static var previews: some View {
ListWithNavigationDestinationTitleBarJumpExample()
}
}
1 ответ
Я считаюNavigationSplitView
запутывается, когда подробный вид имеет.navigationBarTitleDisplayMode
который отличается от того, что вno selection
вид.
Например, большой заголовок или отсутствие заголовка, встроенный заголовок или большой заголовок, заголовок с редактором через привязку или заголовок в виде простого текста.
По крайней мере, твойListWithSelectionTitleBarJumpExample
можно «исправить», добавив заполнитель.navigationTitle
к представлению «без выбора»:
// ...
} else {
Text("No selection")
// The workaround:
.navigationTitle(" ")
}
Это, очевидно, все еще ошибка,NavigationStack
не имеет проблем с переключением между режимами заголовков.