SwiftUI NavigationView с видом прокрутки со стилем PageTabViewStyle()

#swiftui

Вопрос:

Моя цель-получить представление таблицы страниц, содержащее несколько представлений навигации, которые затем содержат представление прокрутки. Я ожидал, что он будет работать с этим кодом:

 struct ContentView: View {
    var body: some View {
        TabView {
            NavigationView {
                ScrollView {
                    Text("Nav 1")
                    Spacer()
                }
                .navigationTitle("Scroll")
            }
            
            NavigationView {
                ScrollView {
                    Text("Nav 2")
                    Spacer()
                }
                .navigationTitle("Scroll 2")
            }
        }
        .tabViewStyle(PageTabViewStyle())
    }
}
 

Но результат в симуляторе таков:

Результат

Для меня здесь важно то, что NavigationView просто содержит представление прокрутки, чтобы при прокрутке можно было изменить заголовок навигации на .inline.

Я делаю здесь что-то не так или это ошибка? Я думаю, что мог бы решить эту проблему с помощью пользовательского представления страниц из UIKit, но я понятия не имею, как реализовать это в SwiftUI.

Я попробовал ответить «Yrb»с помощью StackNavigationViewStyle(). К сожалению, это вызывает у меня странное поведение:

Странное поведение

Ответ №1:

Вам нужно использовать StackNavigationViewStyle() такой:

 struct ContentView: View {
    var body: some View {
        TabView {
            NavigationView {
                ScrollView {
                    Text("Nav 1")
                    Spacer()
                }
                .navigationTitle("Scroll")
                .navigationBarTitleDisplayMode(.inline) // inline added here
            }
            .navigationViewStyle(StackNavigationViewStyle()) //Added here

            NavigationView {
                ScrollView {
                    Text("Nav 2")
                    Spacer()
                }
                .navigationTitle("Scroll 2")
                .navigationBarTitleDisplayMode(.inline) // inline added here
            }
            .navigationViewStyle(StackNavigationViewStyle()) //Added here
        }
        .tabViewStyle(PageTabViewStyle())
    }
}
 

Вы получаете основной подробный вид. Если вы повернете устройство, нажмете стрелку назад, вы увидите его в альбомной ориентации. Использование a StackNavigationViewStyle предотвращает это.

Обычно это входило бы в структуру, которая содержала NavigationView , но из-за вашего (подходящего) простого примера вы NavigationView находитесь в TabView

Редактировать: Это то, на что я намекал, когда говорил «простой пример». Если у вас есть еще какие-либо вопросы по этому поводу, вам нужно задать новый вопрос. ТАКИМ образом, сообщения должны касаться вопроса и двигаться дальше, а не продолжать изменять вопрос. Это потому, что кто-то еще должен видеть, что здесь было сделано, и уметь это использовать. Нечестно по отношению к следующему человеку продолжать их редактировать.

Тем не менее, вот моя последняя правка в коде:

 struct ContentView: View {
    var body: some View {
        TabView {
            Navigation1()
                .tag(0)
            
            Navigation2()
                .tag(1)
        }
        .tabViewStyle(PageTabViewStyle())
    }
}
 

Я добавил к отдельным представлениям:

 struct Navigation1: View {
    var body: some View {
        NavigationView {
            ScrollView {
                HStack{ //Remove this to see your "odd behavior"
                    Text("Navigation 1")
                        .padding()
                } //Remove this to see your "odd behavior"
                Spacer()
            }
            .background(Color.orange)
            .padding(.top, 30)
            .navigationTitle("Scroll 1")
            .navigationBarTitleDisplayMode(.inline) // inline added here
        }
        .navigationViewStyle(StackNavigationViewStyle()) //Added here
    }
}
 

Единственная разница в том, что 1-е заменены на 2-е, и я использовал разные цвета фона. Поведение , которое вы видели, связано с тем, что, когда вы пытались прокрутить Text() , вы на самом деле находились ЗА ПРЕДЕЛАМИ представления прокрутки. Вы можете увидеть это, если удалите HStack из Navigation1 . Цвет фона уменьшится до столбца, и вы увидите, что, если вы попытаетесь прокрутить его снаружи, вы переместите весь вид вверх и вниз. Это ОЖИДАЕМОЕ поведение.

Я добавил отступ, потому что в этом простом примере дизайн пользовательского интерфейса будет выполняться под встроенным заголовком. Вам нужно будет разобраться с этим самостоятельно. Есть много вариантов, но вы должны решить, как вы хотите с этим справиться, и посмотреть его.

Комментарии:

1. Спасибо вам за ваш ответ. К сожалению, это дает мне очень странное поведение .navigationTitle: при прокрутке он не меняется на встроенный и прокручивается с помощью ScrollView. Иногда он меняется на .inline, но это очень запаздывает.

2. Я отредактировал свой ответ. На самом деле это отдельная, но связанная с SwiftUI проблема. Вам нужно добавить .navigationBarTitleDisplayMode(.inline)

3. Я понимаю ваш подход, и я думаю, что был недостаточно ясен: мне нужно, чтобы .navigationTitle менялся только на .inline при прокрутке, как вел бы себя «обычный» навигационный вид с изображением прокрутки.