Skip to content

Commit

Permalink
Improved Tab Bar navigation UX
Browse files Browse the repository at this point in the history
Tab Bar can now go to root if navigation path isn't empty. On SearchView it can open the search field if the navigation path is empty.
Tested on: iOS.

Update packages to their latest versions.
MadeiraAlexandre committed May 20, 2024
1 parent 7d34710 commit 50a9556
Showing 5 changed files with 65 additions and 22 deletions.
4 changes: 3 additions & 1 deletion Shared/View/Navigation/SearchView.swift
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ struct SearchView: View {
@State private var popupType: ActionPopupItems?
@State private var scope: SearchItemsScope = .noScope
@State private var currentlyQuery = String()
@Binding var shouldFocusOnSearchField: Bool
var body: some View {
VStack {
#if os(iOS)
@@ -87,6 +88,7 @@ struct SearchView: View {
}
#if os(iOS) || os(visionOS)
.searchable(text: $viewModel.query,
isPresented: $shouldFocusOnSearchField,
placement: .navigationBarDrawer(displayMode: .always),
prompt: Text("Movies, Shows, People"))
.searchScopes($scope) {
@@ -249,5 +251,5 @@ extension SearchView {
}

#Preview {
SearchView()
SearchView(shouldFocusOnSearchField: .constant(false))
}
2 changes: 1 addition & 1 deletion Shared/View/Navigation/SideBarView.swift
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ struct SideBarView: View {
.environment(\.managedObjectContext, persistence.container.viewContext)
}
case .search:
NavigationStack { SearchView() }
NavigationStack { SearchView(shouldFocusOnSearchField: .constant(false)) }
default:
NavigationStack { HomeView().environment(\.managedObjectContext, persistence.container.viewContext) }
}
69 changes: 55 additions & 14 deletions Shared/View/Navigation/TabBarView.swift
Original file line number Diff line number Diff line change
@@ -9,15 +9,50 @@ import SwiftUI
#if os(iOS) || os(tvOS) || os(visionOS)
/// A TabBar for switching views, only used on iPhone.
struct TabBarView: View {
@AppStorage("selectedView") var selectedView: Screens?
@AppStorage("lastTabSelected") private var tabSelection: Screens?
var persistence = PersistenceController.shared
private var selectedTab: Binding<Screens> {
return .init {
return tabSelection ?? .home
} set: { newValue in
if newValue == tabSelection {
switch newValue {
case .home:
if !homePath.isEmpty {
homePath = .init()
}
case .explore:
if !explorePath.isEmpty {
explorePath = .init()
}
case .watchlist:
if !watchlistPath.isEmpty {
watchlistPath = .init()
}
case .search:
if !searchPath.isEmpty {
searchPath = .init()
} else {
shouldOpenOnSearchField = true
}
default: return
}
}
tabSelection = newValue
}
}
@State private var homePath: NavigationPath = .init()
@State private var explorePath: NavigationPath = .init()
@State private var watchlistPath: NavigationPath = .init()
@State private var searchPath: NavigationPath = .init()
@State private var shouldOpenOnSearchField = false
var body: some View {
details
#if os(iOS)
.onAppear {
let settings = SettingsStore.shared
if settings.isPreferredLaunchScreenEnabled {
selectedView = settings.preferredLaunchScreen
tabSelection = settings.preferredLaunchScreen
}
}
.appTint()
@@ -56,25 +91,31 @@ struct TabBarView: View {

#if os(iOS) || os(visionOS)
private var details: some View {
TabView(selection: $selectedView) {
NavigationStack { HomeView() }
.tag(HomeView.tag)
.tabItem { Label("Home", systemImage: "house") }
TabView(selection: selectedTab) {
NavigationStack(path: $homePath) {
HomeView()
}
.tag(Screens.home)
.tabItem { Label("Home", systemImage: "house") }

NavigationStack { ExploreView() }
.tag(ExploreView.tag)
.tabItem { Label("Discover", systemImage: "popcorn") }
NavigationStack(path: $explorePath) {
ExploreView()
}
.tag(Screens.explore)
.tabItem { Label("Discover", systemImage: "popcorn") }

NavigationStack {
NavigationStack(path: $watchlistPath) {
WatchlistView()
.environment(\.managedObjectContext, persistence.container.viewContext)
}
.tag(WatchlistView.tag)
.tabItem { Label("Watchlist", systemImage: "rectangle.on.rectangle") }
.tag(Screens.watchlist)

NavigationStack { SearchView() }
.tag(SearchView.tag)
.tabItem { Label("Search", systemImage: "magnifyingglass") }
NavigationStack(path: $searchPath) {
SearchView(shouldFocusOnSearchField: $shouldOpenOnSearchField)
}
.tag(Screens.search)
.tabItem { Label("Search", systemImage: "magnifyingglass") }
}
.appTheme()
}
4 changes: 2 additions & 2 deletions Story.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -2231,7 +2231,7 @@
"@executable_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.2;
MARKETING_VERSION = 2.7.1;
MARKETING_VERSION = 2.7.2;
PRODUCT_BUNDLE_IDENTIFIER = dev.alexandremadeira.Story;
PRODUCT_NAME = Cronica;
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2279,7 +2279,7 @@
"@executable_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.2;
MARKETING_VERSION = 2.7.1;
MARKETING_VERSION = 2.7.2;
PRODUCT_BUNDLE_IDENTIFIER = dev.alexandremadeira.Story;
PRODUCT_NAME = Cronica;
PROVISIONING_PROFILE_SPECIFIER = "";
Original file line number Diff line number Diff line change
@@ -15,17 +15,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/kean/Nuke",
"state" : {
"revision" : "4625c73ea00a9fb4b4f3e28d95d0021a44af7e59",
"version" : "12.5.0"
"revision" : "7395c7a9dcd390bbcfad17a731d8d529602702c6",
"version" : "12.7.0"
}
},
{
"identity" : "pow",
"kind" : "remoteSourceControl",
"location" : "https://github.com/EmergeTools/Pow",
"state" : {
"revision" : "cc014eba4b65f689cadc281ad925de5607f2adc9",
"version" : "1.0.3"
"revision" : "f0d0f3e72d42beaf2b01f1cb798e1b55902814eb",
"version" : "1.0.4"
}
},
{

1 comment on commit 50a9556

@MadeiraAlexandre
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Work done for issue #38.

Please sign in to comment.