A SwiftUI TabView substitute (just for the DefaultTabViewStyle, ie, a tabBar at the foot of the screen), with a few customisation options and added extras.
I approached this in a generic way to avoid the use of AnyView for each tab - supposedly there's a performance issue, but regardless of that, this approach uses the pure views. Because it's generic, it is limited to 10 tabs, though that's probably not going to be a problem...
In Xcode:
NB: All examples require
import TabBar
at the top of the source file
var body: some View {
TabBar(selection: viewModel.$currentTab,
{ mapView },
{ placesView }
)
.tabChanged {
viewModel.currentTab = $0
}
.barBackground(viewModel.$tabBarBackground)
.accentColor(Color(.label))
.ignoresSafeArea(edges: .all)
}
You can initialise either with a published selection or without - if you use the selection, you can programmatically change the displayed tab. It currently supports up to 10 tab items.
The views used for each tab must conform to the TabBarContainable protocol, detailed below.
TabBar(selection: viewModel.$currentTab,
{ mapView },
{ placesView }
)
.tabChanged {
viewModel.currentTab = $0
}
In this example, the viewModel is informed of the tab which the user tapped.
You can either set a static background, or use a published value so it can update dynamically.
TabBar(selection: viewModel.$currentTab,
{ mapView },
{ placesView }
)
.barBackground(.color(.black))
TabBar(selection: viewModel.$currentTab,
{ mapView },
{ placesView }
)
.barBackground(viewModel.$tabBarBackground)
The default behaviour of TabBar is to fade between changes, which is noticeable if you have different backgrounds depending on the selected tab. You can disable this & make the changes instant -
TabBar(selection: viewModel.$currentTab,
{ mapView },
{ placesView }
)
.disableBarAnimation
This is the protocol which views used in the TabBar must implement. The requirement is simple - they must provide a TabBarItem value -
struct MyView: TabBarContainable {
let tabBarItem = TabBarItem(name: "Sleep", imageSystemName: "zzz")
Used in its basic form, the tabBarItem is Int indexed, which means that to change tabs, you specify an index. An Int will be returned in the .tabChanged handler as well. You can also use String identifiers, which means that to change tab, you'd have to use that value - likewise, it will be returned in .tabChanged -
let tabBarItem = TabBarItem(name: "Sleep", imageSystemName: "zzz", identifier: "sleepTab")
Currently, only Ints & Strings are supported as identifiers, but it would be easy enough to extend to other types if required. Note that if you use the Int-indexed items, any values you provide for the index are ignored, & it uses the display order for the idexing.
TabBar
is available under the MIT licence.
link |
Stars: 1 |
Last commit: 1 year ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics