Hide Navigation Bar Without Losing Swipe Back Gesture in Swiftui

Hide navigation bar without losing swipe back gesture in SwiftUI

This should work by just extending UINavigationController.

extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}

public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}

How to hide Navigation Bar without losing slide-back ability

Found the solution:

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// hide nav bar
[[self navigationController] setNavigationBarHidden:YES animated:YES];

// enable slide-back
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
}


- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return YES;
}

And in .h file, conform to UIGestureRecognizerDelegate

ios15 half-swiping back while hiding the navigation bar leaves a top empty space - SwiftUI

It's some weird hackery, but I was able to "fix" it by using .navigationViewStyle(.stack) on NavigationView.

If you are interested, btw, the white space was navigation bar and large navigation title. A useful thing in debugging this kind of stuff is the "Debug View Hierarchy" button.
Arrow showing "Debug View Hierarchy" button on debug panel in Xcode 13.1

It's definitely a hack, but you could try submitting a bug report to Apple anyway.

No Swipe Back when hiding Navigation Bar in UINavigationController

A hack that is working is to set the interactivePopGestureRecognizer's delegate of the UINavigationController to nil like this:

[self.navigationController.interactivePopGestureRecognizer setDelegate:nil];

But in some situations it could create strange effects.

Disable swipe-back for a NavigationLink SwiftUI

By hiding the back-button in the navigation bar, the swipe-back gesture is disabled. You can set a custom back-button with .navigationBarItems()

struct ContentView: View {
var body: some View {
NavigationView{
List{
NavigationLink(destination: Text("You can swipe back")){
Text("Child 1")
}
NavigationLink(destination: ChildView()){
Text("Child 2")
}
}
}
}
}

struct ChildView: View{
@Environment(\.presentationMode) var presentationMode

var body:some View{
Text("You cannot swipe back")
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button("Back"){self.presentationMode.wrappedValue.dismiss()})
}
}

Hide navigation bar on swipe of a list in SwiftUI

No native API in SwiftUI so far (both 1.0 & 2.0). So here is a possible working solution based on NavigationConfigurator provided in this answer

Tested with Xcode 12 / iOS 14

Update: retested with Xcode 13.4 / iOS 15.5 - still works fine!

demo

struct TestHideOnSwipe: View {

var body: some View {
NavigationView {
List(0..<100) { i in
Text("Item \(i)")
}
.background(NavigationConfigurator { navigationConfigurator in
navigationConfigurator.hidesBarsOnSwipe = true // << here !!
})
.navigationBarTitle(Text("Demo"), displayMode: .inline)
}
}
}

Test module on GitHub



Related Topics



Leave a reply



Submit