SwiftUI: NavigationDestinationLink устарел
После установки Xcode 11 beta 5 этим утром я заметил, что NavigationDestinationLink
устарела в пользу NavigationLink
,
Кроме того, вот что Apple говорит об этом в примечаниях к выпуску:
NavigationDestinationLink и DynamicNavigationDestinationLink устарели; их функциональность теперь включена в 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
была моя надежда, но это не называется, когда я возвращаюсь к этому... Я не уверен, как мы должны это использовать.
6 ответов
Проведя некоторое время с 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)
}
}
}
}
Чтобы улучшить обходной путь без замены кнопки "Назад" на пользовательскую, используйте приведенный выше код:
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 сотрет значение выбора, предотвращая двойное отображение подробного вида.
Вы также можете использовать NavigationLink(назначение: тег: выбор)
NavigationLink(destination: MyModal(), tag: 1, selection: $tag) {
EmptyView()
}
Таким образом, программно вы можете установить тэг на 1, чтобы нажать MyModal. Этот подход работает так же, как и в случае с переменной связывания Bool, поэтому, когда вы открываете первый раз, он сразу же отображает представление, надеюсь, они исправят это в следующей бета-версии.
Единственный недостаток этого подхода по сравнению с DynamicNavigationDestinationLink заключается в том, что вам нужно предоставить View to NavigationLink, даже если он вам не нужен. Надеемся, что они найдут более чистый способ, позволяющий нам продвигаться программно.
Метод, использованный в выбранном ответе, снова устарел. Вот решение, скопированное из этого ответа в этом посте .
@State private var readyToNavigate : Bool = false
var body: some View {
NavigationStack {
VStack {
Button {
//Code here before changing the bool value
readyToNavigate = true
} label: {
Text("Navigate Button")
}
}
.navigationTitle("Navigation")
.navigationDestination(isPresented: $readyToNavigate) {
MyTargetView()
}
}
}
Решение состоит в том, чтобы вручную создать настраиваемую кнопку возврата для подробного представления и всплывающего подробного представления.
.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))
}
)