swiftuitabbarcontrollerswiftuiuitabbaruitabbaritem

Set TabBar Item badge count with SwiftUI


Is it possible to show TabItem badge with SwiftUI?

It is easy to achieve with UIKit like described here ->

How to set badge value in Tab bar?

I didn't find a way to do this with a SwiftUI. The only possible way is to access to UITabBarController using scene rootViewController and modify its tab bar items directly.

  func setBadgeCount(_ count: Int) {
    UIApplication.shared.applicationIconBadgeNumber = count

    guard let delegate = app.connectedScenes.first?.delegate as? SceneDelegate else {
        return
    }

    if let tabBarController = delegate.window?.rootViewController?.children.first {
      tabBarController.viewControllers?.first?.tabBarItem.badgeValue = "\(count)"
    }
  }

Any ideas how to do this with native SwiftUI approach?


Solution

  • Currently, SwiftUI don't have badge feature so we must custom.

    Reference HERE I create My tabar with badge

    struct ContentView: View {
        private var badgePosition: CGFloat = 2
        private var tabsCount: CGFloat = 2
        @State var selectedView = 0
        var body: some View {
            GeometryReader { geometry in
                ZStack(alignment: .bottomLeading) {
                    TabView {
                        Text("First View")
                            .tabItem {
                                Image(systemName: "list.dash")
                                Text("First")
                            }.tag(0)
                        Text("Second View")
                            .tabItem {
                                Image(systemName: "star")
                                Text("Second")
                            }.tag(1)
                    }
    
                    ZStack {
                      Circle()
                        .foregroundColor(.red)
    
                        Text("3")
                        .foregroundColor(.white)
                        .font(Font.system(size: 12))
                    }
                    .frame(width: 15, height: 15)
                    .offset(x: ( ( 2 * self.badgePosition) - 0.95 ) * ( geometry.size.width / ( 2 * self.tabsCount ) ) + 2, y: -30)
                    .opacity(1.0)
                }
            }
        }
    }