Skip to content

Commit

Permalink
Create PaginatingLazyVStack as a generic scrollable list container
Browse files Browse the repository at this point in the history
  • Loading branch information
amy-at-kickstarter committed Mar 18, 2024
1 parent c558498 commit 742a2d8
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Kickstarter.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,7 @@
E17611E22B73D9A400DF2F50 /* Data+PKCE.swift in Sources */ = {isa = PBXBuildFile; fileRef = E17611E12B73D9A400DF2F50 /* Data+PKCE.swift */; };
E17611E42B751E8100DF2F50 /* Paginator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E17611E32B751E8100DF2F50 /* Paginator.swift */; };
E17611E62B75242A00DF2F50 /* PaginatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E17611E52B75242A00DF2F50 /* PaginatorTests.swift */; };
E1801FA72BA8EDB500EBB533 /* PaginatingLazyVStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1801FA62BA8EDB500EBB533 /* PaginatingLazyVStack.swift */; };
E182E5BA2B8CDFDE0008DD69 /* AppEnvironmentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7ED1F121E830FDC00BFFA01 /* AppEnvironmentTests.swift */; };
E182E5BC2B8D36FE0008DD69 /* AppEnvironmentTests+OAuthInKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = E182E5BB2B8D36FE0008DD69 /* AppEnvironmentTests+OAuthInKeychain.swift */; };
E1A1491E2ACDD76800F49709 /* FetchBackerProjectsQuery.graphql in Resources */ = {isa = PBXBuildFile; fileRef = E1A1491D2ACDD76700F49709 /* FetchBackerProjectsQuery.graphql */; };
Expand Down Expand Up @@ -3138,6 +3139,7 @@
E17611E12B73D9A400DF2F50 /* Data+PKCE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+PKCE.swift"; sourceTree = "<group>"; };
E17611E32B751E8100DF2F50 /* Paginator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Paginator.swift; sourceTree = "<group>"; };
E17611E52B75242A00DF2F50 /* PaginatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginatorTests.swift; sourceTree = "<group>"; };
E1801FA62BA8EDB500EBB533 /* PaginatingLazyVStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaginatingLazyVStack.swift; sourceTree = "<group>"; };
E182E5BB2B8D36FE0008DD69 /* AppEnvironmentTests+OAuthInKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppEnvironmentTests+OAuthInKeychain.swift"; sourceTree = "<group>"; };
E1889D8D2B6065D6004FBE21 /* CombineTestObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineTestObserverTests.swift; sourceTree = "<group>"; };
E1A1491D2ACDD76700F49709 /* FetchBackerProjectsQuery.graphql */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FetchBackerProjectsQuery.graphql; sourceTree = "<group>"; };
Expand Down Expand Up @@ -6111,6 +6113,7 @@
A7ED1F1C1E830FDC00BFFA01 /* PaginateTests.swift */,
E17611E32B751E8100DF2F50 /* Paginator.swift */,
E17611E52B75242A00DF2F50 /* PaginatorTests.swift */,
E1801FA62BA8EDB500EBB533 /* PaginatingLazyVStack.swift */,
373AB25C222A0D8900769FC2 /* PasswordValidation.swift */,
373AB25E222A0DAC00769FC2 /* PasswordValidationTests.swift */,
7703B4232321844900169EF3 /* PKPaymentRequest+Helpers.swift */,
Expand Down Expand Up @@ -7724,6 +7727,7 @@
608E7A5628ABE6CD00289E92 /* SetYourPasswordViewModel.swift in Sources */,
A7F441E11D005A9400FE6FC5 /* ResetPasswordViewModel.swift in Sources */,
94114D83265451FF0063E8F6 /* CommentCellViewModel.swift in Sources */,
E1801FA72BA8EDB500EBB533 /* PaginatingLazyVStack.swift in Sources */,
A734A2671D21A1790080BBD5 /* WKNavigationActionData.swift in Sources */,
8AFB8C97233E9977006779B5 /* CreatePaymentSourceInput+Constructor.swift in Sources */,
774F8D5D22B1B14100A1ACD5 /* FeatureFlagToolsViewModel.swift in Sources */,
Expand Down
114 changes: 114 additions & 0 deletions Library/PaginatingLazyVStack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import Foundation
import SwiftUI

// MARK: Implementation

public struct PaginatingLazyVStack<Data: Identifiable, Cell: View>: View {
@Binding var data: [Data]
@Binding var canShowProgressView: Bool

let onRefresh: () -> Void
let onDidShowProgressView: () -> Void
let configureCell: (Data) -> Cell

public init(
data: Binding<[Data]>,
canShowProgressView: Binding<Bool>,
onRefresh: @escaping () -> Void,
onDidShowProgressView: @escaping () -> Void,
configureCell: @escaping (Data) -> Cell
) {
self._data = data
self._canShowProgressView = canShowProgressView
self.onRefresh = onRefresh
self.onDidShowProgressView = onDidShowProgressView
self.configureCell = configureCell
}

public var body: some View {
ScrollView {
LazyVStack {
ForEach(data) {
configureCell($0)
}
.frame(
maxWidth: .infinity
)
if canShowProgressView {
HStack {
Spacer()
ProgressView()
.progressViewStyle(.circular)
.controlSize(.large)
.onAppear {
onDidShowProgressView()
}
Spacer()
}
}
}
}
.refreshable {
onRefresh()
}
}
}

// MARK: Example view

private struct PaginatingLazyVStackExampleCell: View {
let title: String
var body: some View {
Text(title)
.padding(.all, 10)
.background(.red)
}
}

struct PaginatingExampleModel: Identifiable {
let title: String
let id: String
}

struct PaginatingLazyVStackExampleView: View {
@State var data: [PaginatingExampleModel] = []
@State var hasMore: Bool = true

var body: some View {
PaginatingLazyVStack(
data: $data,
canShowProgressView: $hasMore,
onRefresh: {
data = []
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
addMore()
}
},
onDidShowProgressView: {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
addMore()
}
},
configureCell: { model in
PaginatingLazyVStackExampleCell(title: model.title)
}
)
}

private func addMore() {
for _ in 0...15 {
let uuid = UUID().uuidString
self.data.append(PaginatingExampleModel(
title: "Hello, world \(uuid)",
id: uuid
))
}
if self.data.count > 100 {
self.hasMore = false
}
}
}

#Preview {
PaginatingLazyVStackExampleView()
}

0 comments on commit 742a2d8

Please sign in to comment.