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

Tab Bar Navigation preview #615

Closed
wants to merge 104 commits into from
Closed

Tab Bar Navigation preview #615

wants to merge 104 commits into from

Conversation

boscojwho
Copy link
Contributor

@boscojwho boscojwho commented Sep 17, 2023

Tab Bar Navigation Preview

TL;DR: Try and see if any bug(s) make it totally unusable...plez 🥹

Feature
Users can use the tab bar to navigate back, scroll to top, and show the sidebar.

Discussion
The implementation allows for two types of tab bar navigation actions:

  • System dismiss action (i.e. "go back" when used on a NavigationStack).
  • Auxiliary action, which is loosely defined as any other action that does not involve the system dismiss action.
    ~ Examples include "scroll to top", "focus of search bar", etc. Technically, we could even make it scroll up to each parent comment in ExpandedPost (not that that makes sense =P).
    ~ This auxiliary action is implemented as a () -> Bool closure where you can define multiple "auxiliary sub-actions" by returning true. The tab bar navigator will continue to call into this closure until it returns false.

Implementation Notes
Initially, this feature was implemented by programmatically manipulating a tab's corresponding navigation path.

Unfortunately, this approach is problematic because the navigation path is immediately updated at the beginning of the "go back" animation. While that animation is in-flight, users can initiate further calls that trigger programmatic navigation path manipulation. When that happens, the navigation stack/path data state and UI state become de-synced, and results in some unexpected behaviour when attempting to further manipulate that navigation path.

This revised implementation uses the environment's dismiss action to trigger go back navigation, which means the we let the system deal with coordinating between data state and UI state on a navigation path/stack.

However, this approach has the downside of requiring us to access the DismissAction on each top-level view that can be presented on a navigation stack. is a wrapper around the older, deprecated PresentationMode

Additional Notes
This revision also handles the following use cases:

  • Tab bar navigation still works if user peeks at previous view using drag gesture, then cancels that action.
  • Rapidly tapping on tab to trigger tab bar navigation.

Customization
Currently, there is no option to customize this behaviour. It could make sense to offer one or more of the following options:

  1. Use system behaviour (i.e. always pop to root, then scroll to top).
  2. Go back per page until root page, then scroll to top (then focus on search bar, if API available), and finally pop to sidebar (and scroll to top in sidebar).
  3. Same as 3, but scroll to top on every page.
  4. Turn off entirely.

Todo

  • Check for iOS 17 regressions
  • Add ability to focus on search bar (only available on iOS 17)
  • Review sidebar behaviour on iPad.
  • Clean up API for enabling tab bar navigation (Ideally one-liners, to make it easy to switch to programmatic navigation path manipulation if/when Apple improves that API for our use case.)
  • Documentation

Known Issues

  • Haptic feedback may trigger even if action is ignored because animation is in-flight, causing confusion for users.
  • Haptic feedback is always on.
  • Haptic feedback doesn't play in sidebar.

…eed a reference to a navigation path can use whatever.
- Add tab bar navigation to Inbox/Profile/Search.
Note:
- Need to fix Feed tab navigation.
…ttempting tab bar navigation.

- Add debug print in dismiss action.
- Fix issue where navigationSelection was not the same as selection on init.
- Remove navigation selection state from ContentView.
Note:
- Scroll to top appeared seems broken.
…ld views.

- Remove unused code.
- Add documentation.
- Only scroll to top in user view if it is root view.
…heet view (sheets don't participate in tab bar navigation).
…rag gesture), navigation breaks because SwiftUI doesn't call onAppear again on top view.
…ion no longer works because it lost reference to dismiss action.
Sjmarf and others added 29 commits November 23, 2023 14:51
Co-authored-by: mormaer <[email protected]>
(cherry picked from commit 84fa94c)
(cherry picked from commit 863b05d)
Co-authored-by: Bosco Ho <[email protected]>
(cherry picked from commit 3a2a7c0)
(cherry picked from commit adf639e)
(cherry picked from commit d8bc82c)
Co-authored-by: mormaer <[email protected]>
(cherry picked from commit 57af347)
- Add tab navigation README.
- Hoist function no longer requires dismissAction injection.
- Update README.
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.

5 participants