Max
Max

Reputation: 733

SwiftUI - Change TabBar Icon Color

I can't change the TabBar Color in SwiftUI. I try it with the TabbedView, with the Image/Text and with a Stack. Nothing works for me.

using .foregroundColor doesn't work.

TabbedView(selection: $selection){
 TextView()
  .tag(0)
  .tabItemLabel(
 VStack {
  Image("Calendar")
   .foregroundColor(.red)
  Text("Appointments")
   .foregroundColor(.red)
  }
 ).foregroundColor(.red)
}.foregroundColor(.red)

Upvotes: 32

Views: 28870

Answers (8)

user20791887
user20791887

Reputation: 91

On iOS16 .accentColor(Color) is deprecated. You can use .tint(Color) on the TabView instead.

 TabView {
        Text("First Tab")
            .tabItem {
                Image(systemName: "1.circle")
                Text("First")
            }
 }.tint(Color.yellow)

Upvotes: 7

Eduard Streltsov
Eduard Streltsov

Reputation: 1956

In case you need to set up accent color for entire app with SwiftUI interface, you just need to define AccentColor in Assets.xcassets file like in the picture below. TabBar icons will get it without any additional code.

enter image description here

Upvotes: 1

MichaelMao
MichaelMao

Reputation: 571

I think you can just use the accentColor of TabView,it works for me :]

TabView {
...
}.accentColor(Color.red)

Upvotes: 9

Harry Kim
Harry Kim

Reputation: 911

Solution 1

Use renderingMode(.template)

struct MainView: View {

    var body: some View {
       TabView {
            LoginView().tabItem {
                VStack {
                    Text("Login")
                    Image("login").renderingMode(.template)
                }
            }

            HomeView().tabItem {
                VStack {
                    Text("Home")
                    Image("home").renderingMode(.template)
                }
            }
        }.accentColor(.orange)
    }
}

Solution 2

Make tabItem type

enum TabViewItemType: String {
    case login  = "login"
    case home   = "home"
    case search = "search"

    var image: Image {
        switch self {
        case .login:  return Image("login")
        case .home:   return Image("home")
        case .search: return Image("search")
        }
    }

    var text: Text {
        Text(self.rawValue)
    }
}
struct MainView: View {

    var body: some View {
        TabView {
            LoginView()
                .tabItem { TabViewItem(type: .login) }

            HomeView()
                .tabItem { TabViewItem(type: .home) }

            SearchView()
                .tabItem { TabViewItem(type: .search) }

        }.accentColor(.orange)
    }
}

struct TabViewItem: View {

    var type: TabViewItemType

    var body: some View {
        VStack {
            type.image.renderingMode(.template)
            type.text

        }
    }
}

Upvotes: 48

Ankit
Ankit

Reputation: 131

You can use UITabBar.appearance() to do some customisation until Apple comes with a more standard way of updating SwiftUI TabView

Change TabItem (text + icon) color

init() {
  UITabBar.appearance().unselectedItemTintColor = UIColor.white
}

Change TabView background color

init() {
  UITabBar.appearance().backgroundColor = UIColor.red
  UITabBar.appearance().backgroundImage = UIImage()
}

Overall code looks like this -

struct ContentView: View {

   init() {
       // UITabBar customization
   }

  var body: some View {
     TabView(selection: $selection) {
         FirstTabView()
              .tabItem {
                  VStack {
                     Image(systemName: "map")
                     Text("Near Me")
                  }
              }
     }
  }

}

Use .accentColor modifier for changing color of selected tabItem

After trying many options this worked for me..

Upvotes: 13

Niels Hoogendoorn
Niels Hoogendoorn

Reputation: 738

I made an extension for Image which initialises with a UIImage with a tint color:

extension Image {
    init(_ named: String, tintColor: UIColor) {
        let uiImage = UIImage(named: named) ?? UIImage()
        let tintedImage = uiImage.withTintColor(tintColor,
                                                renderingMode: .alwaysTemplate)
        self = Image(uiImage: tintedImage)
    }
}

Upvotes: 2

Rui Ying
Rui Ying

Reputation: 879

Use accentColor:

        TabView(selection: $selection) {
            NavigationView {
                HomeView()
            }.navigationBarTitle("Home")
                .tabItem {
                    VStack {
                        if selection == 0 {
                            Image(systemName: "house.fill")
                        } else {
                            Image(systemName: "house")
                        }
                        Text("Home")
                    }
                }
            .tag(0)
            NavigationView {
                SettingsView()
            }.navigationBarTitle("Settings")
                .tabItem {
                    VStack {
                        Image(systemName: "gear")
                        Text("Settings")
                    }
                }
                .tag(1)
        }.accentColor(.purple)

Upvotes: 28

Ketan Odedra
Ketan Odedra

Reputation: 1283

Currently SwiftUI does not have a direct method for that.

We've to use the UIKit method for that unless SwiftUI introduces any new solution.

try below code:

struct ContentView: View {

    init() {
        UITabBar.appearance().backgroundColor = UIColor.purple
    }

    var body: some View {
        return TabbedView {
            Text("This is tab 1")
                .tag(0)
                .tabItem {
                    Text("tab1")
            }
            Text("This is tab 2")
                .tag(1)
                .tabItem {
                    Text("tab1")
            }
            Text("This is tab 3")
                .tag(2)
                .tabItem {
                    Text("tab1")
            }
        }
    }
}

Upvotes: 1

Related Questions