代码之家  ›  专栏  ›  技术社区  ›  Osama Naeem

当刷回失败时,SwiftUI导航栏项目会失控

  •  0
  • Osama Naeem  · 技术社区  · 6 年前

    我有一个 ListView , TasksView 然后 EditView .

    流程是这样的:你有一个列表单元格,你点击它,它会把你带到 任务视图 当一行被点击时 任务视图 它会让你 编辑框 .

    当我半滑回导航到上一个视图时,导航栏会出现边框和重叠。它主要发生在我使用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")
              }
         )
    

    同样的道理也适用于 编辑框 当你半刷的时候 编辑框 回到 任务视图 ,同样的事情也会发生。

    下面是正在运行的bug:

    enter image description here

    有人知道如何着手修复这个错误吗?

    编辑:

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

    我甚至没有在应用程序中使用presentationMode deleteList() 函数,以便在删除当前视图时将其关闭。然而,我仍然会遇到上面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")
            }))
    }
    
    }
    }
    

    上面的代码复制了这个bug。当你点击“这是一个测试”按钮,然后向后滑动一点,然后返回到最后一个视图时,你会看到导航栏失控了!

    0 回复  |  直到 6 年前
        1
  •  14
  •   workingdog support Ukraine    6 年前

    我找到了一个简单的解决方案来解决您的问题,将此添加到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")
                }))
        }
    }
    } 
    
        2
  •  2
  •   Aaron Lee    5 年前

    我也曾为同样的问题而挣扎。所以我决定制作一个带有视图修改器的自定义导航栏,我正在使用它。 但我想我现在找到了另一个解决办法。 尝试添加 .isDetailLink(false) 就在那之后 NavigationLink .

    NavigationLink(destination: DestinationView()) {
        Text("This is a test")
    }
    .isDetailLink(false)
    
    
        3
  •  0
  •   mallow    5 年前

    使用 .工具栏 具有 工具栏项 而不是更老 .航海术语 解决了这个问题。

    还请注意,我已将导航修改器移动到 列表 从…起 文本 .

    下面是一个基于您的 使现代化 代码:

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