Create an Interactive Badge List
The Badge
View
Here we create a SwiftUI Badge
that has the ability to switch between different badge types. Right now it includes a .normal
and .removable
type, but can be expanded in the future for further customization.
.normal
- This specific type may be useful in tagging items in our UI which belong to specific categories or topics.
.removable
- This type may be useful when creating a "filter" component for long lists or even a catalog of products for which we want to let the user refine their search.
struct Badge: View {
var name: String
var color: Color = .blue
var type: BadgeType = .normal
enum BadgeType {
case normal
case removable(()->())
}
var body: some View {
HStack{
// Badge Label
Text(name)
.font(Font.caption.bold())
// Add 'x' if removable, and setup tap gesture
switch type {
case .removable( let callback):
Image(systemName: "xmark")
.resizable()
.frame(width: 8, height: 8, alignment: .center)
.font(Font.caption.bold())
.onTapGesture {
callback()
}
default:
EmptyView()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 5)
.background(color)
.cornerRadius(20)
}
}
Example use as a Search Filter
The example below utilizes the .removable
type to show how the badges may be removed from the view by a user's tap gesture.
struct ContentView: View {
@State var filters: [String] = [
"SwiftUI", "Programming", "iOS", "Mobile Development", "😎"
]
var body: some View {
ScrollView (.horizontal, showsIndicators: false) {
HStack {
ForEach(filters, id: \.self) { filter in
Badge(name: filter, color: Color(red: 228/255, green: 237/255, blue: 254/255), type: .removable({
withAnimation {
self.filters.removeAll { $0 == filter }
}
}))
.transition(.opacity)
}
}
.padding(.horizontal, 20)
}
}
}