简体   繁体   English

SwiftUI 导航栏项目在向后滑动失败时出现故障

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

I have a ListView , TasksView and then EditView .我有一个ListViewTasksViewEditView

The flow goes like this: you have a list cell, you tap that which takes you to TasksView When a row is tapped in TasksView it takes you to EditView .流程是这样的:您有一个列表单元格,点击将您带到TasksView的单元格当在TasksView中点击一行时,它会将您带到EditView

When I half swipe back to navigate to previous view the navigation bar go bezerk and overlaps.当我向后滑动一半以导航到上一个视图时,导航栏 go bezerk 并重叠。 It happens mainly if I use a navigationBarItem - (button).它主要发生在我使用navigationBarItem - (按钮)时。

In TasksView (detailView) there is a list and some navigation bar modifiers: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")
          }
     )

Same can be said for EditView , that when you half swipe on EditView to get back to TasksView , the same thing happens. EditView也可以这样说,当您在EditView上轻扫一半以返回TasksView时,会发生同样的事情。

Here is the bug in action:以下是实际操作中的错误:

在此处输入图像描述

Anyone got any idea how to go about fixing this error?有人知道如何 go 解决此错误吗?

EDIT:编辑:

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

    }
  )

I am not even using the presentationMode in the deleteList() function in order to dismiss the current view when it gets deleted.我什至没有在deleteList() function 中使用presentationMode,以便在删除当前视图时将其关闭。 However, I am still getting the same glitch as shown in the gif above.但是,我仍然遇到与上面的 gif 相同的故障。

UPDATE:更新:

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

}
}

The code above reproduces the bug.上面的代码重现了这个错误。 Where when you click "This is a test" button and then you swipe back a bit, and then go back to the last View, you will see the navigation bar going haywire!当您单击“这是一个测试”按钮,然后向后滑动一点,然后 go 回到最后一个视图时,您会看到导航栏变得混乱!

I found a simple solution to fix your problem, add this to the NavigationView我找到了一个简单的解决方案来解决您的问题,将其添加到 NavigationView

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

Edit: This is the code I use to test my answer on real device and various simulators.编辑:这是我用来在真实设备和各种模拟器上测试我的答案的代码。 This fixes the problem, if you find a device where this does not work let me know.这解决了问题,如果您发现无法正常工作的设备,请告诉我。

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

I had struggled with the same issue.我曾在同样的问题上苦苦挣扎。 So I've decided to make a custom nav bar with a view modifier, and I'm using it.所以我决定制作一个带有视图修饰符的自定义导航栏,我正在使用它。 But I think I found another solution now.但我想我现在找到了另一种解决方案。 Try to add .isDetailLink(false) right after the NavigationLink .尝试在NavigationLink之后添加.isDetailLink(false)

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

Using .toolbar with ToolbarItem instead of older .navigationBarItems solves the problem.使用.toolbarToolbarItem而不是旧的.navigationBarItems可以解决问题。

Please also notice that I have moved navigation modifiers to List from Text .另请注意,我已将导航修饰符从Text移至List

Here is a working and tested example based on your UPDATE code:这是一个基于您的更新代码的工作和测试示例:

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.

相关问题 SwiftUI 导航栏标题和项目在向​​后滑动失败时不会消失 - SwiftUI navigation bar title and items does not disappear when swiping back fails 在 UINavigationController 中隐藏导航栏时不向后滑动 - No Swipe Back when hiding Navigation Bar in UINavigationController 取消向后滑动时导航栏闪烁 - Navigation bar flashes when cancelling back swipe 返回时删除导航栏 - Removing Navigation Bar When Going Back 在 SwiftUI 中滑动列表时隐藏导航栏 - Hide navigation bar on swipe of a list in SwiftUI SwiftUI:滑块位于导航栏项目的前导/尾随时的奇怪行为 - SwiftUI: Weird behaviour of Slider when it is in the leading/trailing of navigation bar items ios swift - 返回到隐藏导航栏的屏幕时,导航项背景变为黑色 - ios swift - navigation item background turns black when going back to a screen where the navigation bar is hidden 当第一个视图控制器在 iOS 中隐藏其导航栏时,向后滑动会导致导航栏立即隐藏(不平滑) - Swipe back causes navigation bar hides immediately (not smoothly) when the first view controller hides its navigation bar in iOS 隐藏导航栏但保留返回按钮 - SwiftUI - Hide navigation bar but keep back button - SwiftUI 难以点击 SwiftUI 导航栏项目中的按钮 - Hard to tap button in SwiftUI navigation bar items
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM