Skip to content

Commit 5677e87

Browse files
committed
Added methods to handle currently selected tab state with imperative syntax.
1 parent af9e730 commit 5677e87

10 files changed

+66
-10
lines changed

AxisTabViewExample/Shared/Previews/BasicPreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct BasicPreview: View {
2626
ControlView(selection: $selection, constant: $constant, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
2727
ControlView(selection: $selection, constant: $constant, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
2828
ControlView(selection: $selection, constant: $constant, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
29+
} onTapReceive: { selectionTap in
30+
/// Imperative syntax
31+
print("---------------------")
32+
print("Selection : ", selectionTap)
33+
print("Already selected : ", self.selection == selectionTap)
2934
}
3035
}
3136
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/BeadPreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ struct BeadPreview: View {
8989
systemName: "05.circle.fill",
9090
safeArea: proxy.safeAreaInsets)
9191

92+
} onTapReceive: { selectionTap in
93+
/// Imperative syntax
94+
print("---------------------")
95+
print("Selection : ", selectionTap)
96+
print("Already selected : ", self.selection == selectionTap)
9297
}
9398
}
9499
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/CapsulePreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct CapsulePreview: View {
2626
ControlView(selection: $selection, constant: $constant, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
2727
ControlView(selection: $selection, constant: $constant, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
2828
ControlView(selection: $selection, constant: $constant, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
29+
} onTapReceive: { selectionTap in
30+
/// Imperative syntax
31+
print("---------------------")
32+
print("Selection : ", selectionTap)
33+
print("Already selected : ", self.selection == selectionTap)
2934
}
3035
}
3136
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/CenterPreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ struct CenterPreview: View {
2727
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 2, systemName: "plus.circle.fill", safeArea: proxy.safeAreaInsets)
2828
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
2929
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
30+
} onTapReceive: { selectionTap in
31+
/// Imperative syntax
32+
print("---------------------")
33+
print("Selection : ", selectionTap)
34+
print("Already selected : ", self.selection == selectionTap)
3035
}
3136
}
3237
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/CurveConcavePreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ struct CurveConcavePreview: View {
2828
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
2929
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
3030
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
31+
} onTapReceive: { selectionTap in
32+
/// Imperative syntax
33+
print("---------------------")
34+
print("Selection : ", selectionTap)
35+
print("Already selected : ", self.selection == selectionTap)
3136
}
3237
}
3338
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/CurveConvexPreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ struct CurveConvexPreview: View {
2828
ControlView(selection: $selection, constant: $constant, radius: $radius, convexDepth: $convexDepth, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
2929
ControlView(selection: $selection, constant: $constant, radius: $radius, convexDepth: $convexDepth, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
3030
ControlView(selection: $selection, constant: $constant, radius: $radius, convexDepth: $convexDepth, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
31+
} onTapReceive: { selectionTap in
32+
/// Imperative syntax
33+
print("---------------------")
34+
print("Selection : ", selectionTap)
35+
print("Already selected : ", self.selection == selectionTap)
3136
}
3237
}
3338
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/LinePreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ struct LinePreview: View {
2727
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 2, systemName: "03.square.fill", safeArea: proxy.safeAreaInsets)
2828
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 3, systemName: "04.square.fill", safeArea: proxy.safeAreaInsets)
2929
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 4, systemName: "05.square.fill", safeArea: proxy.safeAreaInsets)
30+
} onTapReceive: { selectionTap in
31+
/// Imperative syntax
32+
print("---------------------")
33+
print("Selection : ", selectionTap)
34+
print("Already selected : ", self.selection == selectionTap)
3035
}
3136
}
3237
.animation(.easeInOut, value: constant)

AxisTabViewExample/Shared/Previews/MaterialPreview.swift

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ struct MaterialPreview: View {
3030
ControlView(selection: $selection, constant: $constant, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
3131
ControlView(selection: $selection, constant: $constant, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
3232
ControlView(selection: $selection, constant: $constant, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
33+
} onTapReceive: { selectionTap in
34+
/// Imperative syntax
35+
print("---------------------")
36+
print("Selection : ", selectionTap)
37+
print("Already selected : ", self.selection == selectionTap)
3338
}
3439
}
3540
.animation(.easeInOut, value: constant)

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ AxisTabView(selection: $selection, constant: ATConstant(axisMode: .bottom)) { st
5050
.bold()
5151
.foregroundColor(Color.yellow)
5252
})
53+
} onTapReceive: { selectionTap in
54+
/// Imperative syntax
55+
print("---------------------")
56+
print("Selection : ", selectionTap)
57+
print("Already selected : ", self.selection == selectionTap)
5358
}
5459
```
5560

Sources/AxisTabView/AxisTabView.swift

+21-10
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,24 @@ import SwiftUI
2727

2828
public struct AxisTabView<SelectionValue, Background, Content> : View where SelectionValue : Hashable, Background : View, Content : View {
2929

30-
private let viewModel: ATViewModel<SelectionValue>
3130
@StateObject private var stateViewModel: ATStateViewModel<SelectionValue> = .init()
32-
31+
private let viewModel: ATViewModel<SelectionValue>
32+
private var selection: Binding<SelectionValue> { Binding(
33+
get: { self.viewModel.selection },
34+
set: {
35+
self.onTapReceive?($0)
36+
self.viewModel.selection = $0
37+
}
38+
)
39+
}
40+
3341
/// Defines the settings for the tab view.
3442
private let constant: ATConstant
3543

3644
/// The style of the background view.
3745
public var background: ((ATTabState) -> Background)
3846
public var content: () -> Content
47+
public var onTapReceive: ((SelectionValue) -> Void)?
3948

4049
public var body: some View {
4150
GeometryReader { proxy in
@@ -47,15 +56,15 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
4756
}
4857
.overlayPreferenceValue(ATTabItemPreferenceKey.self) { items in
4958
let items = items.prefix(getLimitItemCount(size: proxy.size, itemCount: items.count))
50-
let state = ATTabState(constant: constant, itemCount: items.count, previousIndex: stateViewModel.previousIndex, currentIndex: stateViewModel.indexOfTag(viewModel.selection), size: proxy.size, safeAreaInsets: proxy.safeAreaInsets)
59+
let state = ATTabState(constant: constant, itemCount: items.count, previousIndex: stateViewModel.previousIndex, currentIndex: stateViewModel.indexOfTag(selection.wrappedValue), size: proxy.size, safeAreaInsets: proxy.safeAreaInsets)
5160
VStack(spacing: 0) {
5261
if constant.axisMode == .bottom {
5362
Spacer()
5463
}
5564
getTabContent(Array(items))
5665
.frame(width: proxy.size.width, height: constant.tab.normalSize.height)
5766
.padding(edgeSet, getSafeArea(proxy))
58-
.animation(constant.tab.animation ?? .none, value: viewModel.selection)
67+
.animation(constant.tab.animation ?? .none, value: self.selection.wrappedValue)
5968
.background(background(state))
6069
if constant.axisMode == .top {
6170
Spacer()
@@ -76,7 +85,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
7685

7786
//MARK: - Methods
7887
private func getItemWidth(tag: SelectionValue) -> CGFloat {
79-
if tag == self.viewModel.selection {
88+
if tag == self.selection.wrappedValue {
8089
if constant.tab.selectWidth > 0 {
8190
return constant.tab.selectWidth
8291
}
@@ -89,7 +98,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
8998
ForEach(Array(items.enumerated()), id: \.offset) { index, item in
9099
if constant.tab.spacingMode == .center {
91100
ZStack {
92-
if item.tag as! SelectionValue == viewModel.selection {
101+
if item.tag as! SelectionValue == self.selection.wrappedValue {
93102
item.select
94103
.transition(constant.tab.transition)
95104
}else {
@@ -101,7 +110,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
101110
height: constant.tab.normalSize.height)
102111
.onTapGesture {
103112
if let tag = item.tag as? SelectionValue {
104-
self.viewModel.selection = tag
113+
self.selection.wrappedValue = tag
105114
if constant.tab.activeVibration { vibration() }
106115
}
107116
}
@@ -111,7 +120,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
111120
}else {
112121
Spacer()
113122
ZStack {
114-
if item.tag as! SelectionValue == viewModel.selection {
123+
if item.tag as! SelectionValue == self.selection.wrappedValue {
115124
item.select
116125
.transition(constant.tab.transition)
117126
}else {
@@ -123,7 +132,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
123132
height: constant.tab.normalSize.height)
124133
.onTapGesture {
125134
if let tag = item.tag as? SelectionValue {
126-
self.viewModel.selection = tag
135+
self.selection.wrappedValue = tag
127136
if constant.tab.activeVibration { vibration() }
128137
}
129138
}
@@ -175,11 +184,13 @@ public extension AxisTabView where SelectionValue: Hashable, Background: View, C
175184
/// - constant: Defines the settings for the tab view.
176185
/// - background: The style of the background view.
177186
/// - content: Content views with tab items applied.
178-
init(selection: Binding<SelectionValue>, constant: ATConstant = .init(), @ViewBuilder background: @escaping (ATTabState) -> Background, @ViewBuilder content: @escaping () -> Content) {
187+
/// - onTapReceive: Method that treats the currently selected tab as imperative syntax.
188+
init(selection: Binding<SelectionValue>, constant: ATConstant = .init(), @ViewBuilder background: @escaping (ATTabState) -> Background, @ViewBuilder content: @escaping () -> Content, onTapReceive: ((SelectionValue) -> Void)? = nil) {
179189
self.viewModel = ATViewModel(selection: selection, constant: constant)
180190
self.background = background
181191
self.constant = constant
182192
self.content = content
193+
self.onTapReceive = onTapReceive
183194
}
184195
}
185196

0 commit comments

Comments
 (0)