A lightweight, zero-dependency SwiftUI package that gives you a flow-wrapping chip container — use it exactly like HStack or VStack, just drop your views inside.
| Platform | Minimum |
|---|---|
| iOS | 16.0+ |
| macOS | 13.0+ |
| watchOS | 9.0+ |
| tvOS | 16.0+ |
Swift 5.9 · Xcode 15+
In Xcode: File → Add Package Dependencies and paste the repo URL.
Or add it to Package.swift:
dependencies: [
.package(url: "https://github.com/YOUR_USERNAME/ChipView.git", from: "1.0.0")
],
targets: [
.target(name: "YourTarget", dependencies: ["ChipView"])
]import ChipView
ChipView {
ForEach(tags, id: \.id) { tag in
Text(tag.name)
.chipStyle() // built-in convenience modifier
}
}ChipView(hSpacing: 10, vSpacing: 14, alignment: .center) {
ForEach(items, id: \.self) { item in
Text(item)
.chipStyle(background: .purple, foreground: .white)
}
}| Parameter | Type | Default | Description |
|---|---|---|---|
hSpacing |
CGFloat |
8 |
Gap between chips on the same row |
vSpacing |
CGFloat |
8 |
Gap between rows |
alignment |
HorizontalAlignment |
.leading |
.leading / .center / .trailing |
ChipView(hSpacing: 8, vSpacing: 10) {
ForEach(viewModel.concerns, id: \.id) { tag in
let isSelected = viewModel.selectedConcerns.contains(tag.name)
Text(tag.name)
.chipStyle(
background: isSelected ? Color.purple : Color(.systemGray6),
foreground: isSelected ? .white : .primary
)
.onTapGesture {
if isSelected {
viewModel.selectedConcerns.removeAll { $0 == tag.name }
} else {
viewModel.selectedConcerns.append(tag.name)
}
}
}
}ChipView {
ForEach(filters, id: \.self) { filter in
Text(filter)
.outlinedChipStyle(borderColor: .teal, foreground: .teal)
}
}Because ChipView works like HStack, you can put any SwiftUI view inside:
ChipView(hSpacing: 12, vSpacing: 12) {
ForEach(skills, id: \.self) { skill in
HStack(spacing: 4) {
Image(systemName: skill.icon)
Text(skill.name)
}
.chipStyle(background: .blue.opacity(0.12), foreground: .blue)
}
}If a chip's content is wider than the available container width (e.g. a very
long string), ChipView clamps the chip to the container width and passes
that width as the layout proposal — so Text automatically truncates with ….
You do not need to do anything special. Optionally add .lineLimit(1) on your
Text if you want to guarantee single-line truncation:
Text(veryLongString)
.lineLimit(1) // optional — already implied by chipStyle()
.chipStyle()FlowLayout is also public if you need a raw flow container without the
ChipView wrapper:
FlowLayout(hSpacing: 8, vSpacing: 12, alignment: .trailing) {
// any subviews
}| Modifier | Description |
|---|---|
.chipStyle(...) |
Filled background with rounded corners |
.outlinedChipStyle(...) |
Transparent with a border stroke |
Both modifiers accept full customisation: background, foreground,
cornerRadius, verticalPadding, horizontalPadding.
MIT