簡體   English   中英

SwiftUI 導航欄項目在向后滑動失敗時出現故障

[英]SwiftUI navigation bar items going haywire when swipe back fails

我有一個ListViewTasksViewEditView

流程是這樣的:您有一個列表單元格,點擊將您帶到TasksView的單元格當在TasksView中點擊一行時,它會將您帶到EditView

當我向后滑動一半以導航到上一個視圖時,導航欄 go bezerk 並重疊。 它主要發生在我使用navigationBarItem - (按鈕)時。

TasksView (detailView)中有一個列表和一些導航欄修飾符:

ZStack {
   List {
    // code here
 }

}
.onAppear { UITableView.appearance().separatorStyle = .none }
.onDisappear { UITableView.appearance().separatorStyle = .none }
.background(Color("primaryBackground"))
.edgesIgnoringSafeArea(.bottom)
.navigationBarTitle("\(listItem.name ?? "")", displayMode: .inline)
.navigationBarItems(trailing:
    Button(action: {self.deleteList()}) {
              Image(systemName: "trash.circle.fill")
          }
     )

EditView也可以這樣說,當您在EditView上輕掃一半以返回TasksView時,會發生同樣的事情。

以下是實際操作中的錯誤:

在此處輸入圖像描述

有人知道如何 go 解決此錯誤嗎?

編輯:

struct TasksView: View {
@Environment(\.presentationMode) var presentationMode
@EnvironmentObject var taskControl: TaskControl
@EnvironmentObject var addNewTaskData: AddNewTaskViewDataFlow
@ObservedObject var dataPickerData : DatePickerDataFlowV2


@FetchRequest(entity: ONList.entity(), sortDescriptors: []) var listsDataSource: FetchedResults<ONList>
@Environment(\.managedObjectContext) var listMOC

   var listItem: ONList
   var keyboardPublisher: AnyCancellable

 // defining the presentationMode here 

 .......

ZStack {
        NavigationLink(destination: ListOptions(listItem: listItem), tag: 1, selection: self.$navigationSelectionTag) {
            EmptyView()
        }

        Color("primaryBackground")
            .edgesIgnoringSafeArea(.top)

        //... more code here
      }

    .onAppear {

        UITableView.appearance().separatorStyle = .none
        self.taskControl.taskViewerSeperator = true
    }
    .onDisappear {
        UITableView.appearance().separatorStyle = .none
        print("Bye Task View")

        if UIDevice.current.userInterfaceIdiom == .phone {
          self.taskControl.taskViewerSeperator = false
        }

        self.keyboardPublisher.cancel()
    }
    .navigationBarTitle("\(listItem.name ?? "")", displayMode: .inline)
    .background(Color("primaryBackground"))
    .edgesIgnoringSafeArea(.bottom)
    .navigationBarItems(trailing:
        HStack {
        Button(action: {
        self.navigationSelectionTag = 1
    }, label: {
        Image(systemName: "gear")
    })

       Button(action: {
        self.deleteList()

       }) {
          Image(systemName: "trash.circle.fill")

    }.padding()

    }
  )

我什至沒有在deleteList() function 中使用presentationMode,以便在刪除當前視圖時將其關閉。 但是,我仍然遇到與上面的 gif 相同的故障。

更新:

struct TestingCoreData: View {

var body: some View {
    NavigationView {
        VStack {
            NavigationLink(destination: DestinationView()) {
                 Text("This is a test")
            }


        }.navigationBarTitle(Text("Master"), displayMode: .inline)
         .navigationBarItems(trailing:
            Button(action: {
                print("tapped")
            }) {
                Text("Button")
            }

        )
    }
}
}

struct DestinationView: View {

@Environment(\.presentationMode) var presentationMode
var body: some View {

List {
    Text("DestinationView")
        .padding(.top, 100)
        .navigationBarTitle(Text("Destination"), displayMode: .inline)
        .navigationBarItems(trailing: Button(action: {
            self.presentationMode.wrappedValue.dismiss()
        }, label: {
            Text("second")
        }))
}

}
}

上面的代碼重現了這個錯誤。 當您單擊“這是一個測試”按鈕,然后向后滑動一點,然后 go 回到最后一個視圖時,您會看到導航欄變得混亂!

我找到了一個簡單的解決方案來解決您的問題,將其添加到 NavigationView

    NavigationView {
        ....
    }.navigationViewStyle(StackNavigationViewStyle())

編輯:這是我用來在真實設備和各種模擬器上測試我的答案的代碼。 這解決了問題,如果您發現無法正常工作的設備,請告訴我。

import SwiftUI

struct ContentView: View {
var body: some View {
    NavigationView {
        VStack {
            NavigationLink(destination: DestinationView()) {
                Text("This is a test")
            }
        }.navigationBarTitle(Text("Master"), displayMode: .inline)
            .navigationBarItems(trailing:
                Button(action: {
                    print("tapped")
                }) {
                    Text("Button")
            })
    }.navigationViewStyle(StackNavigationViewStyle())
}
}

struct DestinationView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
    List {
        Text("DestinationView")
            .padding(.top, 100)
            .navigationBarTitle(Text("Destination"), displayMode: .inline)
            .navigationBarItems(trailing: Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }, label: {
                Text("second")
            }))
    }
}
} 

我曾在同樣的問題上苦苦掙扎。 所以我決定制作一個帶有視圖修飾符的自定義導航欄,我正在使用它。 但我想我現在找到了另一種解決方案。 嘗試在NavigationLink之后添加.isDetailLink(false)

NavigationLink(destination: DestinationView()) {
    Text("This is a test")
}
.isDetailLink(false)

使用.toolbarToolbarItem而不是舊的.navigationBarItems可以解決問題。

另請注意,我已將導航修飾符從Text移至List

這是一個基於您的更新代碼的工作和測試示例:

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DestinationView()) {
                    Text("This is a test")
                }
            }
            .navigationBarTitle(Text("Master"), displayMode: .inline)
            
            // use .toolbar instead of .navigationBarItems
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing){
                    Button("Button", action: {
                        print("tapped")
                    })
                }
            }
            
        }
    }
}

struct DestinationView: View {
    
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        
        List {
            Text("DestinationView")
                .padding(.top, 100)
        }
        .navigationBarTitle(Text("Destination"), displayMode: .inline)
        // use .toolbar instead of .navigationBarItems
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing){
                Button("second", action: {
                    self.presentationMode.wrappedValue.dismiss()
                })
            }
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM