Skip to content

Commit 3243a4c

Browse files
Implemented single selection mode, multi selection mode and deletable mode
1 parent 2a1074d commit 3243a4c

File tree

4 files changed

+105
-10
lines changed

4 files changed

+105
-10
lines changed

Sources/SwiftChips/ChipsCollectionView.swift

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public struct ChipsCollectionView<D: ChipData>: View {
1111
@Binding public var chips: [D]
1212

1313
public var workingMode: WorkingMode
14+
public var accentColor: Color = .accentColor
1415

1516
public init(chips: Binding<[D]>, mode: WorkingMode = .multipleSelection) {
1617
self._chips = chips
@@ -23,13 +24,7 @@ public struct ChipsCollectionView<D: ChipData>: View {
2324
return GeometryReader { geo in
2425
ZStack(alignment: .topLeading, content: {
2526
ForEach(0 ..< $chips.count, id: \.self) { i in
26-
ChipView(data: self.$chips[i]) { selected in
27-
if workingMode == .singleSelection && selected {
28-
for (index,_) in self.chips.enumerated() where index != i {
29-
self.chips[index].isSelected = false
30-
}
31-
}
32-
}
27+
buildChipView(at: i)
3328
.padding(.all, 5)
3429
.alignmentGuide(.leading) { dimension in
3530
if (abs(width - dimension.width) > geo.size.width) {
@@ -54,8 +49,39 @@ public struct ChipsCollectionView<D: ChipData>: View {
5449
}
5550
}
5651
})
52+
}.environment(\.accentColor, accentColor)
53+
}
54+
55+
// Used for single selection an multiple selection
56+
@ViewBuilder
57+
private func buildChipView(at i: Int) -> some View {
58+
switch workingMode {
59+
case .singleSelection, .multipleSelection:
60+
ChipView(data: self.$chips[i]) { data in
61+
if workingMode == .singleSelection && data.isSelected {
62+
for (index, item) in self.chips.enumerated() where index != i && item.isSelected {
63+
// where isSelected reduce the callbacks to the binding object state to
64+
// only the object that need to be changed
65+
self.chips[index].isSelected = false
66+
}
67+
}
68+
}
69+
case .deletable:
70+
DeletableChipView(data: self.$chips[i]) { data in
71+
withAnimation {
72+
self.$chips.wrappedValue = self.$chips.wrappedValue.filter { $0.id != data.id }
73+
}
74+
}
5775
}
76+
5877
}
78+
79+
// Used only for deletable mode
80+
@ViewBuilder
81+
private func builddDeletableChipView(at i: Int) -> some View {
82+
83+
}
84+
5985
}
6086

6187
struct ContentView_Previews: PreviewProvider {

Sources/SwiftChips/ChipView.swift renamed to Sources/SwiftChips/ChipsViews/ChipView.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,22 @@ import SwiftUI
99
struct ChipView<D: ChipData>: View {
1010
@Binding var data: D
1111

12-
var onTap: (Bool) -> ()
12+
var onTap: (D) -> ()
13+
14+
@Environment(\.accentColor) var userAccentColor
1315

1416
var body: some View {
1517
Text(data.text)
1618
.font(.system(size: 14))
1719
.padding(.horizontal, 10)
1820
.padding(.vertical, 5)
1921
.foregroundColor(data.isSelected ? .white : .black)
20-
.background(data.isSelected ? Color.blue : Color.gray.opacity(0.3))
22+
.background(data.isSelected ? userAccentColor : Color.gray.opacity(0.3))
2123
.cornerRadius(20)
2224
.animation(.spring(), value: data.isSelected)
2325
.onTapGesture {
2426
data.isSelected.toggle()
25-
onTap(data.isSelected)
27+
onTap(data)
2628
}
2729
}
2830
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// SwiftUIView.swift
3+
//
4+
//
5+
// Created by Andrea Ciani on 26.04.23.
6+
//
7+
8+
import SwiftUI
9+
10+
struct DeletableChipView<D: ChipData>: View {
11+
12+
@Binding var data: D
13+
14+
var onTap: (D) -> ()
15+
16+
@Environment(\.accentColor) var userAccentColor
17+
18+
var body: some View {
19+
HStack {
20+
Button {
21+
onTap(data)
22+
} label: {
23+
Image(systemName: "x.circle.fill")
24+
.font(.system(size: 16))
25+
.foregroundColor(.white)
26+
}
27+
Text(data.text)
28+
}
29+
.font(.system(size: 14))
30+
.padding(.horizontal, 10)
31+
.padding(.vertical, 5)
32+
.foregroundColor(data.isSelected ? .white : .black)
33+
.background(userAccentColor)
34+
.cornerRadius(20)
35+
.animation(.spring(), value: data.isSelected)
36+
}
37+
}
38+
39+
struct SwiftUIView_Previews: PreviewProvider {
40+
41+
@State private static var chipState = ExampleChipData(
42+
text: "Example Chip",
43+
isSelected: true)
44+
45+
static var previews: some View {
46+
DeletableChipView(data: $chipState, onTap: {_ in })
47+
}
48+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// EnvironmentKeys.swift
3+
//
4+
//
5+
// Created by Andrea Ciani on 26.04.23.
6+
//
7+
8+
import SwiftUI
9+
10+
struct AccentColorKey: EnvironmentKey {
11+
static let defaultValue: Color = .accentColor
12+
}
13+
14+
extension EnvironmentValues {
15+
var accentColor: Color {
16+
get { self[AccentColorKey.self] }
17+
set { self[AccentColorKey.self] = newValue }
18+
}
19+
}

0 commit comments

Comments
 (0)