Skip to content

Commit

Permalink
Added methods to handle currently selected tab state with imperative …
Browse files Browse the repository at this point in the history
…syntax.
  • Loading branch information
jasudev committed Mar 31, 2022
1 parent af9e730 commit 5677e87
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 10 deletions.
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/BasicPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ struct BasicPreview: View {
ControlView(selection: $selection, constant: $constant, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/BeadPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ struct BeadPreview: View {
systemName: "05.circle.fill",
safeArea: proxy.safeAreaInsets)

} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/CapsulePreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ struct CapsulePreview: View {
ControlView(selection: $selection, constant: $constant, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/CenterPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ struct CenterPreview: View {
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 2, systemName: "plus.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/CurveConcavePreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ struct CurveConcavePreview: View {
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/CurveConvexPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ struct CurveConvexPreview: View {
ControlView(selection: $selection, constant: $constant, radius: $radius, convexDepth: $convexDepth, color: $color, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, convexDepth: $convexDepth, color: $color, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, convexDepth: $convexDepth, color: $color, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/LinePreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ struct LinePreview: View {
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 2, systemName: "03.square.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 3, systemName: "04.square.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, radius: $radius, concaveDepth: $concaveDepth, color: $color, tag: 4, systemName: "05.square.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions AxisTabViewExample/Shared/Previews/MaterialPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ struct MaterialPreview: View {
ControlView(selection: $selection, constant: $constant, tag: 3, systemName: "04.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, tag: 4, systemName: "05.circle.fill", safeArea: proxy.safeAreaInsets)
ControlView(selection: $selection, constant: $constant, tag: 5, systemName: "06.circle.fill", safeArea: proxy.safeAreaInsets)
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
}
.animation(.easeInOut, value: constant)
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ AxisTabView(selection: $selection, constant: ATConstant(axisMode: .bottom)) { st
.bold()
.foregroundColor(Color.yellow)
})
} onTapReceive: { selectionTap in
/// Imperative syntax
print("---------------------")
print("Selection : ", selectionTap)
print("Already selected : ", self.selection == selectionTap)
}
```

Expand Down
31 changes: 21 additions & 10 deletions Sources/AxisTabView/AxisTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,24 @@ import SwiftUI

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

private let viewModel: ATViewModel<SelectionValue>
@StateObject private var stateViewModel: ATStateViewModel<SelectionValue> = .init()

private let viewModel: ATViewModel<SelectionValue>
private var selection: Binding<SelectionValue> { Binding(
get: { self.viewModel.selection },
set: {
self.onTapReceive?($0)
self.viewModel.selection = $0
}
)
}

/// Defines the settings for the tab view.
private let constant: ATConstant

/// The style of the background view.
public var background: ((ATTabState) -> Background)
public var content: () -> Content
public var onTapReceive: ((SelectionValue) -> Void)?

public var body: some View {
GeometryReader { proxy in
Expand All @@ -47,15 +56,15 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
}
.overlayPreferenceValue(ATTabItemPreferenceKey.self) { items in
let items = items.prefix(getLimitItemCount(size: proxy.size, itemCount: items.count))
let state = ATTabState(constant: constant, itemCount: items.count, previousIndex: stateViewModel.previousIndex, currentIndex: stateViewModel.indexOfTag(viewModel.selection), size: proxy.size, safeAreaInsets: proxy.safeAreaInsets)
let state = ATTabState(constant: constant, itemCount: items.count, previousIndex: stateViewModel.previousIndex, currentIndex: stateViewModel.indexOfTag(selection.wrappedValue), size: proxy.size, safeAreaInsets: proxy.safeAreaInsets)
VStack(spacing: 0) {
if constant.axisMode == .bottom {
Spacer()
}
getTabContent(Array(items))
.frame(width: proxy.size.width, height: constant.tab.normalSize.height)
.padding(edgeSet, getSafeArea(proxy))
.animation(constant.tab.animation ?? .none, value: viewModel.selection)
.animation(constant.tab.animation ?? .none, value: self.selection.wrappedValue)
.background(background(state))
if constant.axisMode == .top {
Spacer()
Expand All @@ -76,7 +85,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele

//MARK: - Methods
private func getItemWidth(tag: SelectionValue) -> CGFloat {
if tag == self.viewModel.selection {
if tag == self.selection.wrappedValue {
if constant.tab.selectWidth > 0 {
return constant.tab.selectWidth
}
Expand All @@ -89,7 +98,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
ForEach(Array(items.enumerated()), id: \.offset) { index, item in
if constant.tab.spacingMode == .center {
ZStack {
if item.tag as! SelectionValue == viewModel.selection {
if item.tag as! SelectionValue == self.selection.wrappedValue {
item.select
.transition(constant.tab.transition)
}else {
Expand All @@ -101,7 +110,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
height: constant.tab.normalSize.height)
.onTapGesture {
if let tag = item.tag as? SelectionValue {
self.viewModel.selection = tag
self.selection.wrappedValue = tag
if constant.tab.activeVibration { vibration() }
}
}
Expand All @@ -111,7 +120,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
}else {
Spacer()
ZStack {
if item.tag as! SelectionValue == viewModel.selection {
if item.tag as! SelectionValue == self.selection.wrappedValue {
item.select
.transition(constant.tab.transition)
}else {
Expand All @@ -123,7 +132,7 @@ public struct AxisTabView<SelectionValue, Background, Content> : View where Sele
height: constant.tab.normalSize.height)
.onTapGesture {
if let tag = item.tag as? SelectionValue {
self.viewModel.selection = tag
self.selection.wrappedValue = tag
if constant.tab.activeVibration { vibration() }
}
}
Expand Down Expand Up @@ -175,11 +184,13 @@ public extension AxisTabView where SelectionValue: Hashable, Background: View, C
/// - constant: Defines the settings for the tab view.
/// - background: The style of the background view.
/// - content: Content views with tab items applied.
init(selection: Binding<SelectionValue>, constant: ATConstant = .init(), @ViewBuilder background: @escaping (ATTabState) -> Background, @ViewBuilder content: @escaping () -> Content) {
/// - onTapReceive: Method that treats the currently selected tab as imperative syntax.
init(selection: Binding<SelectionValue>, constant: ATConstant = .init(), @ViewBuilder background: @escaping (ATTabState) -> Background, @ViewBuilder content: @escaping () -> Content, onTapReceive: ((SelectionValue) -> Void)? = nil) {
self.viewModel = ATViewModel(selection: selection, constant: constant)
self.background = background
self.constant = constant
self.content = content
self.onTapReceive = onTapReceive
}
}

Expand Down

0 comments on commit 5677e87

Please sign in to comment.