NavigationLink замикається при спробі переглянути раніше натиснуту кнопку NavigationLink у SwiftUI


10

Я розробляю додаток, який включає функцію отримання даних JSON і відображення списку отриманих елементів у вигляді подання FileBrowser. У цьому режимі користувач повинен мати можливість натиснути на папку, щоб зануритися глибше у дерево файлів або натиснути на файл, щоб переглянути деякі метадані про вказаний файл.

Я помічав, що, коли це працює, коли я клацаю на файл або папку, а потім повертаюся назад і натискаю на неї знову, NavigationLink не спрацьовує, і я застряг у перегляді, поки не натисну інший NavigationLink.

Ось подарунок, який демонструє цю проблему.

Помилка подвійного торкання

Як бачимо тут, коли я натискаю на BlahBlah, я активую NavigationLink і переносяться на BlahBlah, тоді, коли я переходжу назад і намагаюся відновити BlahBlah, він стає сірим, реєструючи, що я натиснув на нього ... але потім ніколи не перевозить мене туди . Клацання на TestFile виправляє це і дозволяє мені повернутися до BlahBlah.

Елементи списку складаються з наступних структур

private struct FileCell{
    var FileName: String
    var FileType: String
    var FileID: String = ""
    var isContainer: Bool
}

private struct constructedCell: View{

    var FileType: String
    var FileName: String
    var FileID: String

    var body: some View {
        return
            HStack{
                VStack(alignment: .center){
                    Image(systemName: getImage(FileType: FileType)).font(.title).frame(width: 50)
                }
                Divider()
                VStack(alignment: .leading){
                    Text(FileName).font(.headline)
                        .multilineTextAlignment(.leading)
                    Text(FileID)
                        .font(.caption)
                        .multilineTextAlignment(.leading)
                }
        }
    }
}

і переглядаються за допомогою навігаційних посилань наступним чином

List(cellArray, id: \.FileID) { cell in
                if (cell.isContainer) {
                    NavigationLink(destination: FileView(path: "/\(cell.FileID)", displaysLogin: self.$displaysLogin).navigationBarTitle(cell.FileName)){
                        constructedCell(FileType: cell.FileType, FileName: cell.FileName, FileID: cell.FileID)
                    }
                } else {
                    NavigationLink(destination: DetailView(FileID: cell.FileID).navigationBarTitle(cell.FileName)){
                        constructedCell(FileType: cell.FileType, FileName: cell.FileName, FileID: cell.FileID)
                    }
                }
            }

Мій NavigationView ініціалізується у поданому вище представленні (додаток має вигляд на вкладці), таким чином

TabView(selection: $selection){
               NavigationView{
                    FileView(displaysLogin: self.$displaysLogin)
                        .navigationBarTitle("Home", displayMode: .inline)
                        .background(NavigationConfigurator { nc in
                            nc.navigationBar.barTintColor = UIColor.white
                            nc.navigationBar.titleTextAttributes = [.foregroundColor : UIColor.black]
                        })
                }
                .font(.title)
                .tabItem {
                    VStack {
                        Image(systemName: "folder.fill")
                        Text("Files")
                    }
                }
                .tag(0)
}

NavigationConfigurator - це структура, яку я використовую для обробки кольору навігаційної смуги. Він налаштований так

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        UIViewController()
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
        if let nc = uiViewController.navigationController {
            self.configure(nc)
        }
    }

}

Я не думаю, що мій NavigationConfigurator викликає це? Ця помилка трапляється і в інших навігаційних посиланнях у додатку, але її було найпростіше продемонструвати тут у вікні FileBrowser.

Це може бути помилка в SwiftUI? Якщо це хтось знає спосіб подолати це? Якщо це не так, що я роблю неправильно?


Я не дуже впевнений. Але ви не повинні загорнути NavigationLinkвсередину NavigationViewта видалити NavigationViewз FileView? Я бачив кілька прикладів, які роблять це саме так.
Джованні

@GiovanniTerlingen Якщо я не розумію, що ти говориш, це я і роблю. NavigationLinkЗнаходиться всередині FileViewякого обгорнутий в NavigationViewтому NavigationLinkобгорнутий внутрішню частинуNavigationView
Vapidant

Будь ласка, надайте мінімальний проект, який можна виконати. Я не можу це відтворити, тому, ймовірно, це не одна з помилок SwiftUI.
Mojtaba

чи можете ви надати повний вихідний код, щоб я міг вирішити вашу проблему
Hardik Bar

як ти готувався cellArray?
E.Coms

Відповіді:


5

Була така ж проблема - спробуйте це. Я б назвав це видалення хака, коли виправлено помилку в swiftUI.

struct ListView: View {
@State private var destID = 0
...
var body: some View {
...
  NavigationLink(destination: FileView(path: "/\(cell.FileID)", displaysLogin: self.$displaysLogin)
   .navigationBarTitle(cell.FileName) 
   .onDisappear() { self.destID = self.destID + 1 }
  ){
   constructedCell(FileType: cell.FileType, FileName: cell.FileName, FileID: cell.FileID) 
  }.id(destID)

По суті, здається, що за деяких обставин (iOS 13.3 - Симулятор?) NavigationLink не скидається, коли вигляд пункту призначення видаляється з навігаційного стеку. Для вирішення проблеми нам потрібно відновити Навігаційне посилання. Ось що робить зміна ідентифікатора. Це виправило мою проблему.

Однак якщо у вас є навігаційні посилання, пов'язані ланцюгом, тобто посилання, що веде до іншого списку посилань, то це рішення створить побічні ефекти; стек повертається до початкового коду при другій спробі показати останній вигляд.


Ця помилка виправлена ​​в останній версії IOS. Я відзначаю це правильною відповіддю, оскільки вирішував питання, як воно стояло, однак це не повинно бути проблемою. Мені також подобається ваше пояснення проблеми. Дякую.
Вапідант

Коли ви говорите останню версію iOS, ви маєте на увазі 13.4 чи бета-версію?
Рікардо Алвеш

Я також хотів би це знати. Яка версія працює правильно? У мене 13,3 (що є останнім iOS зараз), і проблема все ще є.
мальва

Я вважаю, що ця помилка була представлена ​​в бета-версії IOS 13.3, але її було виправлено станом на IOS 13.3 Beta 4.
Vapidant
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.