SwiftUI: проблемы с строкой заголовка NavigationSplitView

Я зарегистрировал это как ошибку в Apple (FB12119822), так как я совершенно уверен, что с моим кодом все в порядке, но публикую здесь для потомков и на случай, если другие люди найдут обходной путь.

При переходе между разделами списка и разделов сведений в NavigationSplitView строка заголовка неожиданно переключается между встроенным и большим режимами отображения. В некоторых случаях заголовок кажется пустым до тех пор, пока переход навигации не будет завершен, после чего он внезапно отображается в режиме большого отображения, сдвигая содержимое представления вниз.

Действия по воспроизведению

  1. Создайте NavigationSplitView с боковой панелью элементов списка, по которым можно перемещаться, и подробное представление, соответствующее выбранному элементу, с заголовком панели навигации.
  2. Перейдите к подробному представлению

Ожидаемый результат

Переход навигации анимирует исходный заголовок в кнопке «Назад» на панели навигации и одновременно анимирует заголовок панели навигации пункта назначения в режим отображения по умолчанию (большой).

Фактический результат

Переход навигации анимирует исходный заголовок в кнопке «Назад» на панели навигации, но заголовок пункта назначения не отображается. Когда переход завершается, текст кнопки «Назад» заменяется текстом по умолчанию («Назад»), и внезапно появляется заголовок места назначения. (запись экрана)

Дополнительные наблюдения

Вышеупомянутое поведение проявляется, когда список 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не имеет проблем с переключением между режимами заголовков.

Другие вопросы по тегам