NavigationLink działa tylko raz

75

Pracowałem nad aplikacją z logowaniem, a po zalogowaniu pojawiają się kategorie. W każdej kategorii znajdują się niektóre pozycje wymienione w poziomie. Rzecz jest po zalogowaniu, pojawia się strona główna i wszystko jest wymienione świetnie. Kliknięcie elementu powoduje przejście do szczegółowego ekranu, ale próba powrotu powoduje awarię. Znalazłem ten przepływ Dlaczego moja aplikacja SwiftUI ulega awarii podczas nawigowania wstecz po umieszczeniu `NavigationLink` wewnątrz` navigationBarItems` w `NavigationView`? ale nie mogłem rozwiązać mojego problemu. Ponieważ mój projekt stał się skomplikowany, chciałem po prostu ćwiczyć nawigację w swiftui i stworzyłem nowy projekt. Nawiasem mówiąc, pobrałem najnowszą wersję xcode 11.3. Napisałem prosty kod w następujący sposób:

NavigationView{
        NavigationLink(destination: Test()) {
            Text("Show Detail View")
        }
    .navigationBarTitle("title1")

Widok Test () jest następujący:

import SwiftUI

struct Test: View {
    var body: some View {
        Text("Hello, World!")
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        Test()
    }
}

Jak widać, jest to naprawdę proste. Próbowałem również podobnych przykładów w Internecie, ale nie działa tak, jak powinien. Kiedy uruchamiam projekt, klikam łącze nawigacyjne i przechodzi do widoku Test (). Następnie klikam przycisk Wstecz i przechodzi do strony głównej. Jednak po drugim kliknięciu łącza nawigacyjnego nic się nie dzieje. Łącze nawigacyjne działa tylko raz, a potem nic się nie dzieje. Nie nawiguje, nie rzuca żadnych błędów. Jestem nowy w swiftui i wszystko jest świetne oprócz nawigacji. Próbowałem wielu przykładów i sugerowałem rozwiązania w Internecie, ale nic nie wydaje się rozwiązać moich problemów.

C.Aglar
źródło
2
wersja xCode 11.2 (11B52), ten kod działa zgodnie z oczekiwaniami zarówno na płótnie, jak i na urządzeniu
Александр Грабовский
3
Przetestowałem twoją migawkę kodu za pomocą Xcode 11.2 / iOS 13.2 - działa dobrze. Spróbuj obniżyć Xcode.
Asperi
1
Xcode wersja 11.2.1 (11B500) Twój kod działa tak, jak musi.
Nalov,
2
Wysłałem recenzję do Apple, pozostaje czekać na przyszłą aktualizację
Александр Грабовский
1
Wysłano raport o błędzie FB7518930
Pacu

Odpowiedzi:

56

[AKTUALIZACJA] 12 lutego 2020 r. - Sprawdziłem ten problem w Xcode 11.4 w wersji beta i stwierdziłem, że problem został rozwiązany.


Ten sam problem występował również w moim projekcie, gdy testowałem go w symulatorze Xcode. Jednak kiedy uruchomiłem aplikację na prawdziwym urządzeniu (iPhone X z iOS 13.3), NavigationLinkdziałało zupełnie dobrze. Naprawdę wygląda to na błąd Xcode.

Sagun Raj Lage
źródło
10
dokładnie tak samo dla mnie. Zaczynam żałować, że wybrałem Swiftui na nową aplikację
TheMouk
6
Właśnie spędziłem 4 godziny, czując się bardzo głupio ... To nie jest gotowe do produkcji ...
Sebastian,
SwiftUI jest nadal w zasadzie wersją 1.0. Czy planujesz kiedykolwiek używać wersji 1.0 jakiejkolwiek wersji produkcyjnej? Zaczynasz od oczekiwania, że ​​poprawi się. To nie pomaga, jeśli musisz zwolnić, zanim to nastąpi.
David Reich,
@DavidReich, jeśli SwiftUI był w fazie beta, mogłem zrozumieć, że będzie wiele problemów. W narzędziach gotowych do produkcji co najmniej trzeba się spodziewać, że to zadziała. Od czasu pierwszego wydania w ubiegłym roku pojawiło się kilka „aktualizacji punktowych” iOS i macOS, więc rażące błędy takie jak ten lub „błąd w tytule listy skoków” powinny były zostać zmiażdżone dawno temu. Próbowałem użyć go do aplikacji produkcyjnej, ale musiałem wrócić do UIKit, aby uzyskać przyzwoity wynik.
GJ Nilsen
3
[AKTUALIZACJA] 12 lutego 2020 r. - Sprawdziłem ten problem w Xcode 11.4 w wersji beta i stwierdziłem, że problem został rozwiązany.
Sagun Raj Lage
5

Symulator 11.4: Ten problem został rozwiązany

Musisz zresetować isActivewartość domyślną w drugim widoku. Działa na urządzeniach i emulatorach.

struct NavigationViewDemo: View {
    @State var isActive = false

    var body: some View {
        NavigationView {
            VStack {
                Text("View1")
                NavigationLink(
                    destination: NavigationViewDemo_View2(isActive: $isActive),
                    isActive: $isActive,
                    label: { Button(action: { self.isActive = true }, label: { Text("click") }) })
            }
        }
    }
}

struct NavigationViewDemo_View2: View {
    @Binding var isActive: Bool

    var body: some View {
        Text("View2")
            .navigationBarItems(leading: Button(action: { self.isActive = false }, label: { Text("Back") }))
    }
}
Victor Kushnerov
źródło
Mam problemy zarówno z symulatorem, jak i z moim urządzeniem fizycznym, gdy NavLink działa więcej niż jeden raz. Nic nie naprawia tego w symulatorze, ale podobną metodą do tej, która działa na moim fizycznym urządzeniu, jest ustawienie onDisappear na View2, która resetuje aktywną flagę. Jest to nieznacznie czystsze obejście błędu Xcode (ponieważ nie musisz wiązać się ze stanem, o którym View2 nie powinien wiedzieć). NavigationViewDemo_View2 (). OnDisappear (wykonaj: {self.isActive = false})
SJoshi
@SJoshi Mam go, ale onDisappear zostanie wywołany po isActivefalse, więc NavigationView nie będzie działał poprawnie. Jest to tymczasowe rozwiązanie dla emulatorów tylko dlatego, że NavigationView działa poprawnie na urządzeniach. W poprzednich wersjach emulatorów nawigacja działała Mam nadzieję, że zostanie to naprawione w przyszłym emulatorze.
Victor Kushnerov
O dziwo, ten kod nie działa na moim symulatorze LUB urządzeniu fizycznym - zaproponowane przeze mnie rozwiązanie resetuje aktywną flagę po odrzuceniu widoku szczegółów i pozwala urządzeniu fizycznemu na działanie.
Mówi
Testowałem na symulatorze 11.3.1, działa jak urok. Widzisz 3 starty, ale chyba inni też pomogli.
Victor Kushnerov
Tak, ja też testowałem na tym - używając wielu iPhone'ów. Testowany również na 4 urządzeniach fizycznych - bez powodzenia. Ten błąd jest zdecydowanie niedorzeczny. W międzyczasie skończyłem w absurdalny sposób obejść ten problem.
SJoshi
1

Ponieważ @ Александр Грабовский powiedział, że to wygląda jak błąd Xcode 11.3, napotykam ten sam problem, musisz obniżyć wersję lub użyć obejścia, takiego jak niestandardowy przycisk powrotu, jak poniżej

struct ContentView: View {
    @State private var pushed: Bool = false

    var body: some View {

        NavigationView {
            VStack {
                Button("Show Detail View") {
                    self.pushed.toggle()
                }

                NavigationLink(destination: Test(pushed: $pushed), isActive: $pushed) { EmptyView() }
            }.navigationBarTitle("title1")
        }
    }
}
struct Test: View {
    @Binding var pushed: Bool
    var body: some View {
        Text("Hello, World!")
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: BackButton(label: "Back") {
                self.pushed = false
            })
    }
}
struct BackButton: View {
    let label: String
    let closure: () -> ()

    var body: some View {
        Button(action: { self.closure() }) {
            HStack {
                Image(systemName: "chevron.left")
                Text(label)
            }
        }
    }
}
ozmpai
źródło