How to display notification count badge in SwiftUI
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)
}
}