Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supported swipe back when NavigationBar is hidden (iOS) #677

Merged
merged 24 commits into from
Mar 18, 2023

Conversation

grahammendick
Copy link
Owner

@grahammendick grahammendick commented Feb 25, 2023

Fixes #664

@RichardLindhout is migrating from RNN to the Navigation router. Migrating all his custom navigation bars over to the Navigation router's native NavigationBar is too much in one go. So he wants to turn off the native navigation bar and use his own for now. But setting hidden to true on the NavigationBar prevents the swipe back gesture on iOS.

There's a difference between setNavigationBarHidden on UINavigationController and setHidden on the UINavigationBar. The first disables the swipe but the second doesn't. I'm not sure if it's official iOS behaviour (it still works on iOS 16).

If the NavigationBar is hidden checked for backTitle to decide which way to hide the navigation bar. If there's a backTitle used setHidden to keep the swipe.

// Swipe disabled
<NavigationBar hidden />

// Swipe enabled
<NavigationBar hidden backTitle="something" />

The original plan was to use the presence of the NavigationBar to determine whether to dis/able the swipe. But the Navigation router doesn’t support a StatusBar without a NavigationBar. Couldn’t hide the navigation bar, keep the swipe and customise the status bar.

While investigating this original plan found a fast way to check for no NavigationBar at all using the NSNotificationCenter. Firing a notification that the NavigationBar receives avoids having to search through all descendant views.

Even though the PR moved away from this plan, kept the NSNotificationCenter in place. Ever since Fabric stole tags, wanted a fast way to find the NavigationBar (replacing viewWithTag). For example, it’s possible to put the NavigationBar at the bottom of the page (Android CoordinatorLayout examples can put it at the bottom) which would’ve meant trawling through all views to find it.

Used notification center to raise event. The navigation bar listens for it and sets itself onto object. It's faster than searching subviews - especially when it might not even be there at all and have to check all subviews
If get the view form the controller then iOS loads the view. This is too early because React Native hasn't finished adding all the children. In particular can't find the navigation bar because it's not part of the subviews yet. So get scene directly instead of from controller
Added crumb to the find notification name so that only the right scene listens. So if there's a stack of 100 scenes only 1 listener fires. It will fire for at most one scene per stack. So if there's tabs it will fire for the matching crumb scene in each stack
Didn't seem to make a difference - it wasn't called even when not manually removing - but good pracitce
Using setHidden instead of setNavigationBarHidden allows the swipe back gesture to work. Good if someone wants to use a custom navigation bar - like Lindhout who's migrating from RNN. Allows him to migrate to the Navigation router stack and still use custom navigation bar
Might be people setting title but not having NavigationBar. V unlikely but want to ensure it's backward compatible - so safe to show the navigation bar if there's a title
Accessing self.view loads the view so viewDidLoad runs before React Native has built the tree. Found this current bug earlier just slipped up again
It's more consistent with android - and it's confusing to check title (v unlikely anyone using title without navigation because can't style it)
Otherwise it's nil when accessed by NVSceneController and falls over
The navigation bar is now visible on Fabric
@grahammendick grahammendick changed the title Hid the UINavigationBar if no NavigationBar rendered (iOS) Hid the UINavigationBar if no NavigationBar (iOS) Feb 25, 2023
Don't want to rely on navigation bar not being there because the status bar only works if the navigation bar is there (what if want not navigation bar, swipe back and status bar). Instead using the back title to decide which type of hide. Hidden with no back title is the default current behaviour. Hidden with back title keeps the swipe
Could, in theory, keep hidden true and toggle backTitle so can enable and disable the swipe. So need to apply different hidden settings inside the NavigaitonBar too. Changed property from hidden to isHidden because hidden is an iOS property already and it kept being set to true when toggling backTitle even if hidden prop stayed false
@grahammendick grahammendick changed the title Hid the UINavigationBar if no NavigationBar (iOS) Enable swipe back when NavigationBar is hidden (iOS) Mar 18, 2023
@grahammendick grahammendick changed the title Enable swipe back when NavigationBar is hidden (iOS) Enabled swipe back when NavigationBar is hidden (iOS) Mar 18, 2023
@grahammendick grahammendick changed the title Enabled swipe back when NavigationBar is hidden (iOS) Supported swipe back when NavigationBar is hidden (iOS) Mar 18, 2023
@grahammendick grahammendick merged commit 5420aba into master Mar 18, 2023
@grahammendick grahammendick deleted the no-navbar branch March 18, 2023 20:43
grahammendick added a commit that referenced this pull request Apr 1, 2023
Errors introduced from PR #677. These props were added for iOS so also needed on fabric
@RichardLindhout
Copy link

It works, thank you!

grahammendick added a commit that referenced this pull request Mar 31, 2024
Used to be that when navigation bar was hidden the swipe back gesture was disabled. So put in #677 to hide navigation bar in a different way to keep the swipe back (turned this on when back title was non-empty). But now the NavigationStack implements UIGestureRecognizerDelegate, and returns YES from gestureRecognizerShouldBegin, the swipe back is automatically enabled even when the navigation bar is hidden. So backing out #677 (on new arch, will do old arch in later commit)
grahammendick added a commit that referenced this pull request Apr 12, 2024
Used to be that when navigation bar was hidden the swipe back gesture was disabled. So put in #677 to hide navigation bar in a different way to keep the swipe back (turned this on when back title was non-empty). But now the NavigationStack implements UIGestureRecognizerDelegate, and returns YES from gestureRecognizerShouldBegin, the swipe back is automatically enabled even when the navigation bar is hidden. So backing out #677 (on old arch, already done on new arch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants