Adding Animation to Tabviews in Swiftui When Switching Between Tabs

Adding animation to TabViews in SwiftUI when switching between tabs

SwiftUI.TabView is one of those Views that just offer the basic Apple look.

You can easily substitute that SwiftUI.TabView with your own so you can add any animations, transitions, colors that work for you app.

import SwiftUI

struct MainTabScreen: View {
@State private var selectedTab: Tabs = .home

var body: some View {
VStack{
//Present only the View that is selected
selectedTab.view()
// You can also apply transitions if you want
//.transition(.slide)
//Have the selected View take up all the available space
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
//This is the "TabView"
HStack{
ForEach(Tabs.allCases, id:\.rawValue){ tab in
tab.label()
//Change the color for the selected case
.foregroundColor(selectedTab == tab ? Color.blue : nil)
//Select the animation and change the tab using your desired abimation
.onTapGesture {
withAnimation(.easeInOut){
selectedTab = tab
}
}
//Stretch the Views so they take up the entire bottom
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)

}
}
//Set the height of the TabView
.frame( height: 80, alignment: .center)
}

}
//Enum that keeps track of the New TabView's Views
enum Tabs:String,CaseIterable,CustomStringConvertible{
case home
case dollar
case menu
///Formatted name for the View
var description: String{
rawValue.capitalized
}
///Image that represents the View
@ViewBuilder func image() -> some View{
switch self {
case .home:
Image(systemName: "house")
case .dollar:
Image(systemName: "dollarsign.circle")
case .menu:
Image(systemName: "plus")
}
}
///Primary View for the tab
@ViewBuilder func view() -> some View{
switch self {
case .home:
Text("Home()")
case .dollar:
Text("Dollar()")
case .menu:
Text("Menu()")
}
}
///Label for the TabView
@ViewBuilder func label() -> some View{
switch self {
default:
VStack{
image()
Text(description)
}
}
}
}
}

struct MainTabScreen_Previews: PreviewProvider {
static var previews: some View {
MainTabScreen()
}
}

Sample Image

SwiftUI TabView Animation

1.with .transition() we only specify which transition should happen.

2.Transition occur (as expected), only when explicit animation occurs.

3.Animation occurs when change happened(State, Binding)

here is one of possible approaches.

    struct ContentView: View {
@State private var selection: Int = 1
var body: some View {
TabView(selection: $selection,
content: {
ItemView(text:"1")
.tabItem { Text("tab1") }.tag(1)
ItemView(text: "2")
.tabItem { Text("tab2") }.tag(2)
})

}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}


struct ItemView: View {
let text: String
@State var hidden = true

var body: some View {
VStack {
if !hidden {
Text("Tab Content " + text)
.transition(.slide)
}
}
.onAppear() { withAnimation {
hidden = false
}}
.onDisappear(){hidden = true}

}
}

SwiftUI: animating tab item addition/removal in tab bar

As commented Apple wants the TabBar to stay unchanged throughout the App.

But you can simply implement your own Tabbar with full control:

struct ContentView: View {

@State private var currentTab = "One"
@State var showBoth: Bool = false

var body: some View {
VStack {
TabView(selection: $currentTab) {
// Tab 1.
VStack {
Button("Toggle 2. Tab") {
withAnimation {
showBoth.toggle()
}
}
} .tag("One")

// Tab 2.
VStack {
Text("Two")
} .tag("Two")
}

// custom Tabbar buttons
Divider()
HStack {
OwnTabBarButton("One", imageName: "1.circle")

if showBoth {
OwnTabBarButton("Two", imageName: "2.circle")
.transition(.scale)
}
}
}
}

func OwnTabBarButton(_ label: String, imageName: String) -> some View {
Button {
currentTab = label
} label: {
VStack {
Image(systemName: imageName)
Text(label)
}
}
.padding([.horizontal,.top])
}
}


Related Topics



Leave a reply



Submit