NavigationLink работает только один раз


75

Я работал над приложением с логином, и после логина были перечислены категории. И под каждой категорией есть несколько пунктов, перечисленных по горизонтали. Дело в том, что после входа в систему появляется главная страница, и все в порядке. Когда вы нажимаете на элемент, он переходит на подробный экран, но при попытке вернуться он просто падает. Я обнаружил этот поток Почему мое приложение SwiftUI аварийно завершает работу при перемещении назад после размещения `NavigationLink` внутри` navigationBarItems` в `NavigationView`?но я не мог решить мою проблему. Поскольку мой проект стал сложным, я просто хотел попрактиковаться в навигации на swiftui и создал новый проект. Кстати я скачал последнюю версию XCode 11.3. Я написал простой код следующим образом:

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

И представление Test () выглядит следующим образом:

import SwiftUI

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

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

Как видите, это действительно просто. Я также пробовал подобные примеры в интернете, но это не работает так, как предполагается. Когда я запускаю проект, я нажимаю на навигационную ссылку, и она переходит к представлению Test (). Затем я нажимаю кнопку «Назад», и она переходит на главную страницу. Однако, когда я нажимаю на навигационную ссылку во второй раз, ничего не происходит. Навигационная ссылка работает только один раз и после этого ничего не происходит. Он не перемещается, он не выдает никакой ошибки. Я новичок в swiftui и все отлично, но навигация. Я пробовал много примеров и предлагал решения в Интернете, но, кажется, ничто не решает мои проблемы.


2
версия xCode 11.2 (11B52), этот код работает как ожидалось как на холсте, так и на устройстве
Александр Грабовский

3
Протестировал ваш снимок кода с Xcode 11.2 / iOS 13.2 - работает хорошо. Попробуйте понизить Xcode.
Аспери

1
Версия Xcode 11.2.1 (11B500) ваш код работает как надо.
Налов

2
Я отправил отзыв в Apple, осталось дождаться будущего обновления
Александр Грабовский

1
Отправлено сообщение об ошибке FB7518930
Pacu

Ответы:


56

[ОБНОВЛЕНИЕ] 12 февраля 2020 г. - Я проверил эту проблему в бета-версии Xcode 11.4 и обнаружил, что эта проблема была решена.


Я столкнулся с той же проблемой в своем проекте, когда тестировал ее в симуляторе XCode. Однако, когда я запустил приложение на реальном устройстве (iPhone X с iOS 13.3), оно NavigationLinkработало совершенно нормально. Итак, это действительно похоже на ошибку Xcode.


10
точно так же для меня. Я начинаю сожалеть, что выбрал Swiftui для нового приложения
theMouk

6
я просто провел 4 часа, чувствуя себя очень глупо ... Этот материал не готов к производству ...
Себастьян

SwiftUI по-прежнему в основном версии 1.0. Планируете ли вы когда-либо использовать v 1.0 для промышленного выпуска? Вы начинаете с этого с надеждой, что это улучшится. Это не поможет, если вам нужно выпустить до того, как это произойдет.
Дэвид Рейх

@DavidReich, если бы SwiftUI был в бета-версии, я мог бы понять, что будет много проблем. В готовом инструменте, по крайней мере, следует ожидать, что он работает. Со времени первоначального выпуска в прошлом году было несколько «точечных обновлений» iOS и macOS, поэтому такие явные ошибки, как эта, или «ошибка заголовка списка переходов» должны были быть устранены давным-давно. Я пытался использовать его для производственного приложения, но мне пришлось вернуться к UIKit, чтобы получить достойный результат.
GJ Нильсен

3
[ОБНОВЛЕНИЕ] 12 февраля 2020 г. - Я проверил эту проблему в бета-версии Xcode 11.4 и обнаружил, что эта проблема была решена.
Сагун Радж Лаге

5

Симулятор 11.4: эта проблема была исправлена

Вам необходимо сбросить isActiveзначение по умолчанию во втором представлении. Работает на устройствах и эмуляторах.

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") }))
    }
}

У меня проблемы как с симулятором, так и с моим физическим устройством из-за того, что NavigationLink работал более одного раза. Ничто не исправляет это в симуляторе, но метод, подобный этому, который работает для моего физического устройства, устанавливает onDisappear на View2, который сбрасывает активный флаг. Это немного более чистый обходной путь для ошибки XCode (потому что вам не нужно привязываться к состоянию, о котором View2 не должен знать). NavigationViewDemo_View2 (). OnDisappear (выполнить: {self.isActive = false})
Джоши

@SJoshi Я получил это, но onDisappear будет вызван после того, isActiveкак ложь, поэтому NavigationView не будет работать должным образом. Это временное решение для эмуляторов только потому, что NavigationView корректно работает на устройствах. В предыдущих версиях эмуляторов NavigationView работал, надеюсь, это будет исправлено в будущем эмуляторе.
Виктор Кушнеров

Как ни странно, этот код не работает на моем симуляторе ИЛИ на физическом устройстве - предлагаемое мной решение сбрасывает активный флаг, когда детализируется представление, и позволяет физическому устройству работать.
Известно,

Я тестировал на симуляторе 11.3.1, он работает как шарм. Вы видите 3 запуска, я думаю, что другие тоже помогли.
Виктор Кушнеров

Да, я тоже, проверенный на том - используя многократные iPhone. Также проверено на 4 физических устройствах - не повезло. Эта ошибка определенно нелепа. Я закончил тем временем нелепым обходным путем для симулятора.
Джоши

3

Предположительно, это будет решено, когда Apple исправит связанную ошибку, которая не позволяет выбрать 13.3 в качестве цели развертывания. .

Я испытываю ту же проблему, что и все остальные. Эта проблема присутствует в симуляторе и предварительном просмотре под управлением 13.2, но исправлена ​​при развертывании на моем собственном устройстве под управлением 13.3.


1

Как сказал @ Александр Грабовский, это похоже на ошибку Xcode 11.3, я столкнулся с той же проблемой, вы должны понизить версию или использовать какой-то обходной путь, например пользовательскую кнопку возврата, как показано ниже

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)
            }
        }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.