How to display notification count badge in SwiftUI

Ondrej Kvasnovsky
2 min readFeb 4, 2023

--

We are going to implement a simple notification count badge that we can attach to an icon (or any other view using overlay function).

Count of notification view

Here is a simple notification view that:

  • displays the circle or oval based on number of notifications
  • displays the number of notifications, if the number is too big, we display “99+”
import SwiftUI

struct NotificationCountView : View {

@Binding var value: Int
@State var foreground: Color = .white
@State var background: Color = .red

private let size = 16.0
private let x = 20.0
private let y = 0.0

var body: some View {
ZStack {
Capsule()
.fill(background)
.frame(width: size * widthMultplier(), height: size, alignment: .topTrailing)
.position(x: x, y: y)

if hasTwoOrLessDigits() {
Text("\(value)")
.foregroundColor(foreground)
.font(Font.caption)
.position(x: x, y: y)
} else {
Text("99+")
.foregroundColor(foreground)
.font(Font.caption)
.frame(width: size * widthMultplier(), height: size, alignment: .center)
.position(x: x, y: y)
}
}
.opacity(value == 0 ? 0 : 1)
}

// showing more than 99 might take too much space, rather display something like 99+
func hasTwoOrLessDigits() -> Bool {
return value < 100
}

func widthMultplier() -> Double {
if value < 10 {
// one digit
return 1.0
} else if value < 100 {
// two digits
return 1.5
} else {
// too many digits, showing 99+
return 2.0
}
}
}

Using it

We add the NotificationCountView to a view, like bell icon, using the overlay function.

struct NotificationCountView_Previews: PreviewProvider {
static var previews: some View {
VStack(spacing: 32) {
Image(systemName: "bell")
.foregroundColor(Color.white)
.overlay(
NotificationCountView(value: .constant(0))
)

Image(systemName: "bell")
.foregroundColor(Color.white)
.overlay(
NotificationCountView(value: .constant(5))
)

Image(systemName: "bell")
.foregroundColor(Color.white)
.overlay(
NotificationCountView(value: .constant(50))
)

Image(systemName: "bell")
.foregroundColor(Color.white)
.overlay(
NotificationCountView(value: .constant(1000))
)

Button(action: {
// TODO:
}, label: {
Image(systemName: "bell")
.foregroundColor(Color.white)
.overlay(
NotificationCountView(
value: .constant(9),
foreground: .white,
background: .green
)
)
})
}
.scaleEffect(3.0)
.preferredColorScheme(.dark)
}
}

--

--

No responses yet