SwiftUI: NavigationDestinationLink устарел

После установки Xcode 11 beta 5 сегодня утром я заметил, что NavigationDestinationLink устарела в пользу NavigationLink.

Кроме того, вот что Apple говорит об этом в примечаниях к выпуску:

NavigationDestinationLink and DynamicNavigationDestinationLink are deprecated; their functionality is now included in NavigationLink. (50630794)

То, как я использую NavigationDestinationLink, заключается в программном добавлении нового представления в стек через self.link.presented?.value = true. Похоже, что этой функции нет в NavigationLink.

Любая идея? Я бы предпочел больше не использовать NavigationDestinationLink, так как он устарел...

Благодарю вас!

Обновлено: На самом деле, способ NavigationDestinationLink больше не работает, так что, я думаю, у нас больше нет возможности программно нажать?

ОБНОВЛЕНИЕ 2:

NavigationLink(destination: CustomView(), isActive: $isActive) {
    return Text("")
}

Это работает, но когда вы передаете isActive значение true, любое обновление состояния будет запускать этот код и отправлять его снова и снова... Кроме того, если вы передадите его обратно в false, он выскочит из представления. Не только обновления, если вы установите isActive на true, это подтолкнет вид (хорошо), и если мы нажмем кнопку «Назад», он вернется, а затем сразу же снова нажмет, так как это все еще верно. Игра с onAppear была моей надеждой, но она не вызывается, когда я возвращаюсь к ней... Я не уверен, как мы должны использовать это.

NavigationLink(destination: Your view()) ? Разве это не должно работать?

LearningPhase 30.07.2019 16:26

Интересует и это. Нигде не могу найти замену.

Thomas Vos 30.07.2019 17:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
2
9 932
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

Проведя некоторое время с NavigationLink(destination:isActive), он мне нравится намного больше, чем старый NavigationDestinationLink. Старый вид был немного запутанным, в то время как новый подход кажется гораздо более элегантным. И как только я выясню, как продвигать без анимации, это сделает восстановление состояния при запуске приложения очень простым.

Но есть одна проблема, большая и уродливая ошибка. :-(

Нажатие представления программно работает нормально, и его программное извлечение тоже. Проблема начинается, когда мы используем кнопку НАЗАД в нажатом представлении, которая каждый раз ведет себя странно. В первый раз, когда представление всплывает, представление всплывает и сразу же подталкивает снова. Со второго раза работает нормально. Потом в третий раз все сначала.

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

Я разработал обходной путь, который в основном состоит из замены кнопки «Назад» по умолчанию на нашу собственную:

class Model: ObservableObject {
    @Published var pushed = false
}

struct ContentView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        NavigationView {
            VStack {
                Button("Push") {
                    // view pushed programmatically
                    self.model.pushed = true
                }

                NavigationLink(destination: DetailView(), isActive: $model.pushed) { EmptyView() }
            }
        }
    }
}

struct DetailView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        Button("Bring me Back (programatically)") {
            // view popped programmatically
            self.model.pushed = false
        }
        // workaround
        .navigationBarBackButtonHidden(true) // not needed, but just in case
        .navigationBarItems(leading: MyBackButton(label: "Back!") {
            self.model.pushed = false
        })
    }
}

struct MyBackButton: View {
    let label: String
    let closure: () -> ()

    var body: some View {
        Button(action: { self.closure() }) {
            HStack {
                Image(systemName: "chevron.left")
                Text(label)
            }
        }
    }
}

Да, смотри, я только что написал об этом в своем «Обновлении 2» :(

Benjamin Clanet 30.07.2019 16:57

Это действительно интересно, спасибо, что поделились. Тем не менее, он все еще имеет другое поведение. Раньше DetailView создавался только один раз. Теперь он создается каждый раз при обновлении ContentView. Это вызывает у меня некоторые проблемы, связанные со сбросом состояния подробного представления. Я создал новый вопрос по моей проблеме. Я был бы очень признателен за вашу помощь. stackoverflow.com/q/57289150/4583267

Thomas Vos 31.07.2019 13:02
Примечание:EmptyView() по-прежнему использует пробел. Это видно по тому, что кнопка находится над центральной линией. Я нахожу это довольно раздражающим.
philipp 02.10.2019 23:40

@philipp Пространство занято NavigationLink, а не EmptyView. В любом случае, вы всегда можете добавить NavigationLink(...) {..}.frame(width: 0, height: 0).

kontiki 03.10.2019 07:28

@kontiki отличная идея. Я изо всех сил пытаюсь загрузить новое представление навигации из представления коллекции UIKit. Этот трюк и использование NavigationLink (тега) должны помочь.

philipp 05.10.2019 07:52

Вы также можете использовать NavigationLink(destination:tag:selection)

NavigationLink(destination: MyModal(), tag: 1, selection: $tag) {
    EmptyView()
}

Таким образом, программно вы можете установить тег равным 1, чтобы нажать MyModal. Этот подход имеет то же поведение, что и вариант с переменной привязки Bool, поэтому, когда вы выталкиваете в первый раз, он сразу же отправляет представление, надеюсь, они исправят это в следующей бета-версии.

Единственный недостаток, который я вижу в этом подходе по сравнению с DynamicNavigationDestinationLink, заключается в том, что вам нужно предоставить View для NavigationLink, даже если он вам не нужен. Будем надеяться, что они найдут более чистый способ, позволяющий нам выполнять push программно.

Чтобы улучшить обходной путь без замены кнопки «Назад» пользовательской, вы можете использовать приведенный выше код:

NavigationLink(destination: Test().onAppear(perform: {
    self.editPushed = nil
}), tag: 1, selection: self.$editPushed) {
    Button(action: {
        self.editPushed = 1
    }) {
        Image(systemName: "plus.app.fill")
            .font(.title)
    }
}

Блок onAppear удалит значение выбора, предотвращая двукратное отображение подробного представления.

Это работает, но, похоже, не позволяет мне программно перейти от подробного представления к основному представлению.

Fabian Streitel 15.09.2019 11:48

Я обнаружил, что извлечение текущего представления из стека навигации работает, как описано здесь: stackoverflow.com/a/57594164/1396068

Fabian Streitel 15.09.2019 11:54

Решение состоит в том, чтобы создать пользовательскую кнопку «Назад» для вашего подробного представления и открыть подробное представление вручную.

.navigationBarItems(leading:
                Button(action: {
                    self.showDetail = false
                }) {
                    Image(systemName: "chevron.left").foregroundColor(.red)
                        .font(.system(size: 24, weight: .semibold))
                    Text("Back").foregroundColor(.red)
                    .font(.system(size: 19))
                }
            )

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