Skip to content

Commit

Permalink
Added support for Horizontal ScrollViews
Browse files Browse the repository at this point in the history
  • Loading branch information
smbrmoyo committed Oct 12, 2024
1 parent 41dbdba commit 5a41144
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 10 deletions.
15 changes: 15 additions & 0 deletions Sources/InfiniteScrollView/Enums/InfiniteAxis.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// InfiniteAxis.swift
// InfiniteScrollView
//
// Created by Brian Moyou on 12.10.24.
//

/**
`InfiniteAxis` represents the possible Axes for either a VStack or an HStack
- `horizontal`: Horizontal Axis
- `vertical`: Vertical Axis
*/
public enum InfiniteAxis {
case horizontal, vertical
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
// Created by Brian Moyou on 12.10.24.
//

import Foundation

/**
`UIState` represents the current state of the infinite scroll view.
- `idle`: The default state where the list is displayed or is empty.
- `loading`: The state where the list is being loaded or refreshed.
*/
public enum UIState {
case idle
case loading
case idle, loading
}
30 changes: 30 additions & 0 deletions Sources/InfiniteScrollView/Helpers/LazyVHStack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// LazyVHStack.swift
// InfiniteScrollView
//
// Created by Brian Moyou on 12.10.24.
//

import SwiftUI

@available(macOS 12.0, *)
public struct LazyVHStack<Content: View>: View {
let axis: Axis
let spacing: CGFloat
@ViewBuilder let content: () -> Content

public var body: some View {
Group {
switch axis {
case .vertical:
LazyVStack(spacing: spacing) {
content()
}
case .horizontal:
LazyHStack(spacing: spacing) {
content()
}
}
}
}
}
35 changes: 35 additions & 0 deletions Sources/InfiniteScrollView/Helpers/VHScrollView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// VHScrollView.swift
// InfiniteScrollView
//
// Created by Brian Moyou on 12.10.24.
//

import SwiftUI

@available(macOS 12.0, *)
public struct VHScrollView<Content: View>: View {
var axis: Axis = .vertical
var refresh: () async -> () = {}
@ViewBuilder let content: () -> Content

public var body: some View {
Group {
switch axis {
case .vertical:
ScrollView {
content()
}
.refreshable {
try? await Task.sleep(nanoseconds: 500_000_000)
await refresh()
}
case .horizontal:
ScrollView(.horizontal) {
content()
}
}
}
}
}

29 changes: 29 additions & 0 deletions Sources/InfiniteScrollView/Helpers/VHStack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// VHStack.swift
// InfiniteScrollView
//
// Created by Brian Moyou on 12.10.24.
//

import SwiftUI

@available(macOS 12.0, *)
public struct VHStack<Content: View>: View {
var axis: Axis = .vertical
@ViewBuilder let content: () -> Content

public var body: some View {
Group {
switch axis {
case .vertical:
VStack {
content()
}
case .horizontal:
HStack {
content()
}
}
}
}
}
16 changes: 10 additions & 6 deletions Sources/InfiniteScrollView/InfiniteScrollView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ public struct InfiniteScrollView<

// MARK: - Properties

private let axis: InfiniteAxis
public var items: [T]
@State public var isLoadingMore = false
@Binding public var canLoadMore: Bool
@State private var isLoadingMore = false
@Binding private var canLoadMore: Bool
public var uiState: UIState
public var spacing: CGFloat = 8

Expand All @@ -43,14 +44,16 @@ public struct InfiniteScrollView<
- emptyView: A `View` to display when the list is empty.
- row: A `View` to display for each item in the list.
*/
public init(items: [T],
public init(axis: InfiniteAxis = .horizontal,
items: [T],
canLoadMore: Binding<Bool>,
uiState: UIState,
spacing: CGFloat = 8,
loadMoreItems: @escaping () async -> () = {},
refresh: @escaping () async -> () = {},
@ViewBuilder emptyView: @escaping () -> EmptyContent,
@ViewBuilder row: @escaping (T) -> Content) {
self.axis = axis
self.items = items
self._canLoadMore = canLoadMore
self.uiState = uiState
Expand All @@ -64,10 +67,11 @@ public struct InfiniteScrollView<
// MARK: - Body

public var body: some View {
VStack {
Group {
if !items.isEmpty && uiState == .idle {
ScrollView {
LazyVStack(spacing: spacing) {
VHScrollView(axis: axis == .vertical ? .vertical : .horizontal) {
LazyVHStack(axis: axis == .vertical ? .vertical : .horizontal,
spacing: spacing) {
ForEach(items) { item in
row(item)
}
Expand Down

0 comments on commit 5a41144

Please sign in to comment.