Check out the tab views used in Apples apps: Podcast, Music, Files... Switching between tabs is always instantaneous, by design.
Personally I don't think a transition animation between the tabs would add any benefit. It could even get annoying for a user.
If you really want to trigger some animation, you could use the onAppear
of each tab to build some illusion... but this would mean that your views (within the TabView) would really need to know what view is being drawn left/right of it. I think you will end up writing your own version of TabView, not a good idea.
See also the HIG to learn why and when to use tab bars (https://developer.apple.com/design/human-interface-guidelines/tab-bars) in iOS.
But if you really need an animation... there is a possible way using the TabView
in .page
mode. The TabView
will take care of the animation and will allow swiping between the screens, but you will have to add the bottom bar with all the buttons to switch between the pages. See the example below.
struct ContentView: View {
@State private var selectedScreen = 0
var body: some View {
TabView(selection: $selectedScreen) {
Text("Home")
.tag(0)
Text("Calendar")
.tag(1)
Text("Settings")
.tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .never))
.toolbar {
ToolbarItem(placement: .bottomBar) {
HStack {
Button(action: { withAnimation { selectedScreen = 0 } }) {
VStack {
Image(systemName: "house")
Text("Home").font(.caption2)
}
}
.foregroundColor(selectedScreen == 0 ? .accentColor : .primary)
.frame(maxWidth: .infinity)
Button(action: { withAnimation { selectedScreen = 1 } }) {
VStack {
Image(systemName: "calendar")
Text("Calendar").font(.caption2)
}
}
.foregroundColor(selectedScreen == 1 ? .accentColor : .primary)
.frame(maxWidth: .infinity)
Button(action: { withAnimation { selectedScreen = 2 } }) {
VStack {
Image(systemName: "gear")
Text("Settings").font(.caption2)
}
}
.foregroundColor(selectedScreen == 2 ? .accentColor : .primary)
.frame(maxWidth: .infinity)
}
.buttonStyle(.plain)
.labelStyle(.titleAndIcon)
}
}
}
}