Как по-прежнему использовать боковую панель после навигации по представлению PadOS?

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

В данный момент происходит следующее: я прекрасно выбираю страницы на боковой панели, а затем в основном представлении. Если я нажимаю кнопку, которая перемещает меня от этого основного представления к другому, боковая панель становится бесполезной. Мне нужно нажать «Назад», чтобы вернуться к исходному виду, выбранному на боковой панели, и тогда боковая панель снова станет активной.

В примере приложения - если вы перейдете к «wx по прибытии» на боковой панели, а затем нажмите кнопку «Перейти к настройкам» на «второй уровень», боковая панель не будет работать...

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

Вот очень простая воспроизводимая версия проблемы, прошу прощения за много страниц:

import SwiftUI

@main
struct scrapAppApp: App {
    var body: some Scene {
        WindowGroup {
            MenuView()
        }
    }
}

funcs.swift

class AppState: ObservableObject {
    @Published var destination: String = ""
    @Published var path = NavigationPath()
    @Published var selectedItem: SidebarItem?
    @Published var readyToNavigate : Bool = false
    
}

МенюView.swift

enum SidebarItem: String, Identifiable, CaseIterable {
    case initialScreen = "Initial Screen"
    case arrivalWx = "Wx On Arrival"
    case legal = "Legal"

    var id: String { self.rawValue }

    var iconName: String {
        switch self {
        case .initialScreen:
            return "house"
        case .arrivalWx:
            return "cloud.sun"
        case .legal:
            return "doc.text"
        }
    }
}

struct MenuView: View {
    @StateObject private var app = AppState()
    
    var body: some View {
        NavigationSplitView {
            List(SidebarItem.allCases, id: \.self, selection: $app.selectedItem) { item in
                NavigationLink(value: item) {
                    Label(item.rawValue, systemImage: item.iconName)
                }
            }
            .listStyle(SidebarListStyle())
            .navigationTitle("Menu")
        } detail: {
            NavigationStack(path: $app.path) {
                if let selectedItem = app.selectedItem {
                    switch selectedItem {
                    case .initialScreen:
                        FirstPage()
                    case .arrivalWx:
                        SecondPage(app: app)
                    case .legal:
                        FourthPage(app: app)
                    }
                } else {
                    Text("Select an item")
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                }
            }
        }
    }
}

FirstPage.swift

struct FirstPage: View {
    var body: some View {
        Text("INITIAL SCREEN")
    }
}

SecondPage.swift

struct SecondPage: View {
    
    @ObservedObject var app: AppState
    
    var body: some View {
        Text("WX on ARRIVAL")
        Button("Go settings") {
            app.readyToNavigate = true
        }
        .navigationDestination(isPresented: $app.readyToNavigate) {
            ThirdPage()
        }
    }
}

Третья страница.swift

struct ThirdPage: View {
    
    @ObservedObject var app = AppState()
    
    var body: some View {
        Text("Second Layer")
    }
}

Четвертая страница.swift

struct FourthPage: View {
    @ObservedObject var app: AppState
    
    var body: some View {
        Button("LEGAL") {
        }
    }
}

AFAIK, в iPadOS в портретном режиме это поведение по умолчанию. В ландшафтном режиме вы можете одновременно использовать боковую панель и навигацию. Обратите внимание: поскольку вы используете AppState во многих дочерних представлениях, я рекомендую вам использовать .environmentObject(app) в представлении сверху и в дочерних представлениях @EnvironmentObject var app: AppState вместо того, чтобы передавать модель повсюду с возможными ошибками, как при ThirdPage повторном объявлении модели.

workingdog support Ukraine 25.06.2024 08:28

Спасибо @workingdog, поддержите Украину. Сейчас я перешел на EnvironmentObject. Я пробовал в альбомной ориентации, и, похоже, он ведет себя так же, где - после нажатия кнопки «Перейти к настройкам» элементы боковой панели не действуют. Я также заметил, что если на странице «Настройки» нажать «Юридические» на боковой панели, то при нажатии «Назад» отображается страница «Юридическая»… Сбивает с толку.

PW1990 25.06.2024 13:01

Я не понимаю никаких твоих проблем. Вы говоритеI want to be able to select a page and then navigate within that selected page to other pages. Такое поведение я наблюдаю на iPadOS 17.5.1. Кроме того ...the sidebar becomes useless, я вообще этого не понимаю, боковая панель постоянно реагирует. Я опубликую свой тестовый код.

workingdog support Ukraine 25.06.2024 13:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот мой тестовый код, который работает на iPadOS 17.5.1.

struct MenuView: View {
    @StateObject private var app = AppState()

    var body: some View {
        NavigationSplitView {
            List(SidebarItem.allCases, selection: $app.selectedItem) { item in
                NavigationLink(value: item) {
                    Label(item.rawValue, systemImage: item.iconName)
                }
            }
            .listStyle(SidebarListStyle())
            .navigationTitle("Menu")
        } detail: {
            NavigationStack(path: $app.path) {
                if let selectedItem = app.selectedItem {
                    switch selectedItem {
                    case .initialScreen:
                        FirstPage()
                    case .arrivalWx:
                        SecondPage()
                    case .legal:
                        FourthPage()
                    }
                } else {
                    Text("Select an item")
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                }
            }
            .environmentObject(app)  // <--- here
        }
    }
}

class AppState: ObservableObject {
    @Published var destination: String = ""
    @Published var path = NavigationPath()
    @Published var selectedItem: SidebarItem?
    @Published var readyToNavigate: Bool = false
}

enum SidebarItem: String, Identifiable, CaseIterable {
    case initialScreen = "Initial Screen"
    case arrivalWx = "Wx On Arrival"
    case legal = "Legal"

    var id: String { self.rawValue }

    var iconName: String {
        switch self {
        case .initialScreen:
            return "house"
        case .arrivalWx:
            return "cloud.sun"
        case .legal:
            return "doc.text"
        }
    }
}

struct FirstPage: View {
    @EnvironmentObject var app: AppState // not used
    
    var body: some View {
        Text("FirstPage INITIAL SCREEN")
    }
}

struct SecondPage: View {
    @EnvironmentObject var app: AppState
    
    var body: some View {
        Text("SecondPage WX on ARRIVAL")
        Button("Go settings") {
            app.readyToNavigate = true
        }
        .navigationDestination(isPresented: $app.readyToNavigate) {
            ThirdPage()
        }
    }
}

struct ThirdPage: View {
    @EnvironmentObject var app: AppState  // not used
    
    var body: some View {
        Text("ThirdPage Second Layer")
    }
}

struct FourthPage: View {
    @EnvironmentObject var app: AppState  // not used
    
    var body: some View {
        Button("FourthPage LEGAL") {
        }
    }
}

Обратите внимание: я хотел сказать, что в портретном режиме боковая панель исчезает, но в альбомном режиме она остается видимой.

Большое спасибо @workingdog, поддержка Украины. Я скопировал и вставил ваш код дословно. Я получаю то же поведение, что и раньше. Когда я говорю, что это становится бесполезным, я имею в виду, что когда я нахожусь на Третьей странице, на которую перешел с помощью кнопки, нажатие «Начальный экран» или «Юридические вопросы» на боковой панели не приводит к навигации. Мне нужно нажать кнопку «Назад», прежде чем навигация через боковую панель станет видимой. Если это то, что вы получаете и ожидаемое поведение, не беспокойтесь, я поработаю с этим. Спасибо!

PW1990 25.06.2024 23:26

Интересно, может ли одновременный жест() сработать для очистки NavigationPath() при нажатии элемента боковой панели? Хотя я не уверен, что это правильный путь.

PW1990 25.06.2024 23:33

Как я уже сказал, у меня нет подобных проблем с моим кодом. Когда я нахожусь на третьей странице, на которую перешел с помощью кнопки, нажатие кнопки «Начальный экран» или «Юридические данные» на боковой панели позволяет мне перемещаться. Боковая панель активна. Какую систему вы используете и нацеливаетесь. Сейчас я использую MacOS 15, бета-версию Xcode 16, целевую iOS-17.5, протестирован на реальном (более старом) устройстве iPad и MacCatalyst.

workingdog support Ukraine 26.06.2024 01:10

Хорошо, я использовал симулятор, и он не работал. Сейчас я запустил его на настоящем iPad, и он работает хорошо. Я использую MacOS 14.2 Xcode 15 и нацелен на iOS 17 или новее. iPad, над которым он работает, — iOS 17.3. Спасибо за помощь, очень ценю.

PW1990 26.06.2024 05:49

Рад, что теперь это работает. Если мой ответ вам помог, примите его, отметив галочку рядом с ним, она станет зеленой.

workingdog support Ukraine 26.06.2024 06:18

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