我有一个使用自定义导航栏的 SwiftUI 应用程序。因此,我需要单独处理后退导航(后退按钮和滑动手势)。到目前为止一切都很好,当我需要使用 TabView 在页面之间滑动时。下面的代码说明了我想要实现的目标:
内容视图.swift
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: SecondView()) {
Text("Go to second view")
}
}
}
}
SecondView.swift
import SwiftUI
// Being able to go back by swiping
// https://stackoverflow.com/questions/59921239/hide-navigation-bar-without-losing-swipe-back-gesture-in-swiftui
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
struct SecondView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack(alignment: .leading) {
Image(systemName: "chevron.left")
.foregroundColor(Color(.systemBlue))
.font(.title2)
.onTapGesture {
self.presentationMode.wrappedValue.dismiss()
}
.padding()
TabView {
Text("Test 1")
.tag(1)
Text("Test 2")
.tag(1)
Text("Test 3")
.tag(3)
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
.background(Color(.systemGray6))
.navigationBarHidden(true)
}
}
请注意,我没有为第二个视图添加自定义导航栏,我只是隐藏了默认导航栏,因为不需要自定义栏来解决这个问题。
当用户在里面SecondView
并按下后退按钮时,一切都按预期工作。当他尝试向后滑动时会出现问题,因为 TabView 捕获了向后滑动手势。我想保留 TabView 的“页面间滑动”功能,同时能够返回到ContentView
用户从屏幕最左侧向右滑动时的状态。
此问题仅在使用TabView
s 时出现,其他类型的内容处理向后滑动手势没有问题。
为了解决这个问题,我可以TabView
像这样添加一个水平填充:
TabView {
// content
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.padding(.horizontal)
然后用户将有一些空间可以向后滑动,但是当内部的某些视图TabView
需要占用屏幕的整个宽度时,这种解决方案就不是很好了。
在这种特殊情况下,有没有办法处理向后滑动手势?也许另一种可能的解决方案是自定义 TabView 以在显示第一个视图并捕获向右滑动手势时忽略拖动手势(我不知道如何实现)。