Skip to content
This repository was archived by the owner on Nov 4, 2022. It is now read-only.

Commit 91d85a3

Browse files
Merge pull request #127 from apptekstudios/dev
V1.5.0 candidate
2 parents d03a4ed + 019be61 commit 91d85a3

21 files changed

Lines changed: 596 additions & 476 deletions

ASCollectionView-SwiftUI.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Pod::Spec.new do |s|
33
s.name = 'ASCollectionView-SwiftUI'
4-
s.version = '1.4.2'
4+
s.version = '1.5.0'
55
s.summary = 'A SwiftUI collection view with support for custom layouts, preloading, and more. '
66

77
s.description = <<-DESC

Demo/ASCollectionViewDemo.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
B8268B542363EF1B008C99A3 /* GroupLarge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8268B532363EF1B008C99A3 /* GroupLarge.swift */; };
1212
B8268B562363EF25008C99A3 /* GroupSmall.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8268B552363EF25008C99A3 /* GroupSmall.swift */; };
1313
B8268B582363EF37008C99A3 /* GroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8268B572363EF37008C99A3 /* GroupModel.swift */; };
14+
B82DD9892435D16C004D303E /* README code content.swift in Sources */ = {isa = PBXBuildFile; fileRef = B82DD9882435D16C004D303E /* README code content.swift */; };
1415
B8384F542366E9FD0049CA47 /* TagStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89129FD235DB71900D8BA90 /* TagStore.swift */; };
1516
B86C6F17234B078600522AEF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86C6F16234B078600522AEF /* AppDelegate.swift */; };
1617
B86C6F19234B078600522AEF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86C6F18234B078600522AEF /* SceneDelegate.swift */; };
@@ -45,6 +46,7 @@
4546
B8268B532363EF1B008C99A3 /* GroupLarge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupLarge.swift; sourceTree = "<group>"; };
4647
B8268B552363EF25008C99A3 /* GroupSmall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupSmall.swift; sourceTree = "<group>"; };
4748
B8268B572363EF37008C99A3 /* GroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupModel.swift; sourceTree = "<group>"; };
49+
B82DD9882435D16C004D303E /* README code content.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "README code content.swift"; sourceTree = "<group>"; };
4850
B86C6F13234B078600522AEF /* ASCollectionViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ASCollectionViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
4951
B86C6F16234B078600522AEF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
5052
B86C6F18234B078600522AEF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@@ -103,6 +105,7 @@
103105
isa = PBXGroup;
104106
children = (
105107
B8D8292D2371077400D3F0AE /* SampleUsage.swift */,
108+
B82DD9882435D16C004D303E /* README code content.swift */,
106109
B86C6F15234B078600522AEF /* ASCollectionViewDemo */,
107110
B86C6F14234B078600522AEF /* Products */,
108111
B86C6F2C234B0B7D00522AEF /* ASCollectionView */,
@@ -362,6 +365,7 @@
362365
B86C6F47234B0B9D00522AEF /* Post.swift in Sources */,
363366
B899D70123752CEC001BB5FA /* WaterfallScreen.swift in Sources */,
364367
B86C6F49234B0B9D00522AEF /* PhotoGridScreen.swift in Sources */,
368+
B82DD9892435D16C004D303E /* README code content.swift in Sources */,
365369
B86C6F4E234B0B9D00522AEF /* StoryView.swift in Sources */,
366370
B86C6F4D234B0B9D00522AEF /* InstaFeedScreen.swift in Sources */,
367371
B86C6F4C234B0B9D00522AEF /* PostView.swift in Sources */,

Demo/ASCollectionViewDemo/Screens/InstaFeed/InstaFeedScreen.swift

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,11 @@ struct InstaFeedScreen: View
2424
{
2525
.list(itemSize: .absolute(100), sectionInsets: NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
2626
}
27-
.frame(height: 100)
28-
.collectionViewScrollIndicatorsEnabled(false)
29-
.collectionViewOnReachedBoundary
30-
{ boundary in
27+
.onReachedBoundary { boundary in
3128
print("Reached the \(boundary) boundary")
3229
}
30+
.scrollIndicatorsEnabled(horizontal: false, vertical: false)
31+
.frame(height: 100)
3332
}
3433

3534
var storiesSection: ASTableViewSection<Int>
@@ -57,38 +56,33 @@ struct InstaFeedScreen: View
5756
{
5857
VStack(spacing: 0)
5958
{
60-
HStack
61-
{
62-
Text("Demo sticky header view")
63-
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
64-
Spacer()
65-
}
59+
Text("Section \(i)")
60+
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
61+
.frame(maxWidth: .infinity, alignment: .leading)
6662
Divider()
6763
}
6864
.background(Color(.secondarySystemBackground))
6965
}
7066
}
7167
}
7268

73-
var sections: [ASTableViewSection<Int>]
74-
{
75-
[storiesSection] + postSections
76-
}
77-
7869
var body: some View
7970
{
80-
ASTableView(sections: sections)
81-
.tableViewSeparatorsEnabled(false)
82-
.onPullToRefresh { endRefreshing in
83-
print("PULL TO REFRESH")
84-
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in
85-
endRefreshing()
86-
}
87-
}
88-
.tableViewOnReachedBottom
71+
ASTableView {
72+
storiesSection // An ASSection
73+
postSections // An array of ASSection's
74+
}
75+
.onReachedBottom
8976
{
9077
self.loadMoreContent() // REACHED BOTTOM, LOADING MORE CONTENT
9178
}
79+
.separatorsEnabled(false)
80+
.onPullToRefresh { endRefreshing in
81+
print("PULL TO REFRESH")
82+
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in
83+
endRefreshing()
84+
}
85+
}
9286
.navigationBarTitle("Insta Feed (tableview)", displayMode: .inline)
9387
}
9488

Demo/ASCollectionViewDemo/Screens/MagazineLayout/MagazineLayoutScreen.swift

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,10 @@ struct MagazineLayoutScreen: View
2323
}
2424
.sectionSupplementary(ofKind: MagazineLayout.SupplementaryViewKind.sectionHeader)
2525
{
26-
HStack
27-
{
28-
Text("Section \(offset)")
29-
.padding()
30-
Spacer()
31-
}
32-
.background(Color.blue)
26+
Text("Section \(offset)")
27+
.padding()
28+
.frame(maxWidth: .infinity, alignment: .leading)
29+
.background(Color.blue)
3330
}
3431
}
3532
}
@@ -38,13 +35,12 @@ struct MagazineLayoutScreen: View
3835
{
3936
ASCollectionView(sections: self.sections)
4037
.layout { MagazineLayout() }
38+
.onReachedBoundary { boundary in
39+
print("Reached the \(boundary) boundary")
40+
}
4141
.customDelegate(ASCollectionViewMagazineLayoutDelegate.init)
4242
.edgesIgnoringSafeArea(.all)
4343
.navigationBarTitle("Magazine Layout (custom delegate)", displayMode: .inline)
44-
.collectionViewOnReachedBoundary
45-
{ boundary in
46-
print("Reached the \(boundary) boundary")
47-
}
4844
}
4945

5046
func onCellEvent(_ event: CellEvent<Post>)

Demo/ASCollectionViewDemo/Screens/PhotoGrid/PhotoGridScreen.swift

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ struct PhotoGridScreen: View
2626
data: data,
2727
selectedItems: $selectedItems,
2828
onCellEvent: onCellEvent,
29-
onDragDropEvent: onDragDropEvent,
3029
itemProvider: { item in
3130
// Example of returning a custom item provider (eg. to support drag-drop to other apps)
3231
NSItemProvider(object: item.url as NSURL)
@@ -70,8 +69,8 @@ struct PhotoGridScreen: View
7069
ASCollectionView(
7170
section: section)
7271
.layout(self.layout)
72+
.initialScrollPosition(startingAtBottom ? .bottom : nil)
7373
.edgesIgnoringSafeArea(.all)
74-
.collectionViewInitialScrollPosition(startingAtBottom ? .bottom : nil)
7574
.navigationBarTitle("Explore", displayMode: .large)
7675
.navigationBarItems(
7776
trailing:
@@ -80,7 +79,10 @@ struct PhotoGridScreen: View
8079
if self.isEditing
8180
{
8281
Button(action: {
83-
self.data.remove(atOffsets: IndexSet(self.selectedItems))
82+
withAnimation {
83+
// We want the cell removal to be animated, so explicitly specify `withAnimation`
84+
self.data.remove(atOffsets: IndexSet(self.selectedItems))
85+
}
8486
})
8587
{
8688
Image(systemName: "trash")
@@ -123,20 +125,6 @@ struct PhotoGridScreen: View
123125
}
124126
.navigationBarTitle("", displayMode: .inline)
125127
}
126-
127-
func onDragDropEvent(_ event: DragDrop<Post>)
128-
{
129-
switch event
130-
{
131-
case let .onRemoveItem(indexPath):
132-
if data.containsIndex(indexPath.item)
133-
{
134-
data.remove(at: indexPath.item)
135-
}
136-
case let .onAddItems(items, indexPath):
137-
data.insert(contentsOf: items, at: min(indexPath.item, data.endIndex))
138-
}
139-
}
140128
}
141129

142130
extension PhotoGridScreen

Demo/ASCollectionViewDemo/Screens/Reminders/RemindersScreen.swift

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,11 @@ struct RemindersScreen: View
4646
}
4747
.sectionHeader
4848
{
49-
HStack
50-
{
51-
Text("My Lists")
52-
.font(.headline)
53-
.bold()
54-
.padding()
55-
Spacer()
56-
}
49+
Text("My Lists")
50+
.font(.headline)
51+
.bold()
52+
.padding()
53+
.frame(maxWidth: .infinity, alignment: .leading)
5754
}
5855

5956
ASCollectionViewSection<Section>(id: .addNew)
@@ -63,18 +60,14 @@ struct RemindersScreen: View
6360

6461
ASCollectionViewSection<Section>(id: .footnote)
6562
{
66-
HStack
67-
{
68-
Spacer()
69-
Text("Try rotating the screen")
70-
.padding()
71-
Spacer()
72-
}
63+
Text("Try rotating the screen")
64+
.padding()
65+
.frame(maxWidth: .infinity, alignment: .center)
7366
}
7467
}
7568
.layout(self.layout)
76-
.collectionViewContentInsets(.init(top: 20, left: 0, bottom: 20, right: 0))
77-
.collectionViewAlwaysBounceVertical()
69+
.contentInsets(.init(top: 20, left: 0, bottom: 20, right: 0))
70+
.alwaysBounceVertical()
7871
.background(Color(.systemGroupedBackground))
7972
.edgesIgnoringSafeArea(.all)
8073
.navigationBarTitle("Reminders", displayMode: .inline)

Demo/ASCollectionViewDemo/Screens/Tags/TagsScreen.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ struct TagsScreen: View
2626
}
2727
.onTapGesture
2828
{
29-
self.store.refreshStore()
29+
withAnimation(self.shrinkToSize ? nil : .default) {
30+
self.store.refreshStore()
31+
}
3032
}
3133
Text("Tags:")
3234
.font(.title)

Demo/ASCollectionViewDemo/Screens/Waterfall/WaterfallScreen.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ struct WaterfallScreen: View
9292
sections: sections)
9393
.layout(self.layout)
9494
.customDelegate(WaterfallScreenLayoutDelegate.init)
95-
.collectionViewContentInsets(.init(top: 0, left: 10, bottom: 10, right: 10))
95+
.contentInsets(.init(top: 0, left: 10, bottom: 10, right: 10))
9696
.navigationBarTitle("Waterfall Layout", displayMode: .inline)
9797
.navigationBarItems(
9898
trailing:
@@ -101,8 +101,10 @@ struct WaterfallScreen: View
101101
if self.isEditing
102102
{
103103
Button(action: {
104-
self.selectedItems.forEach { sectionIndex, selected in
105-
self.data[sectionIndex].remove(atOffsets: IndexSet(selected))
104+
withAnimation {
105+
self.selectedItems.forEach { sectionIndex, selected in
106+
self.data[sectionIndex].remove(atOffsets: IndexSet(selected))
107+
}
106108
}
107109
})
108110
{

Demo/README code content.swift

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// ASCollectionView. Created by Apptek Studios 2019
2+
3+
// This file is built with the demo project to ensure the sample code used in the readme is valid
4+
5+
import ASCollectionView
6+
import SwiftUI
7+
8+
struct READMEContent
9+
{
10+
// MARK: EXAMPLE 1
11+
12+
struct SingleSectionExampleView: View
13+
{
14+
@State var dataExample = (0 ..< 30).map { $0 }
15+
16+
var body: some View
17+
{
18+
ASCollectionView(data: dataExample, dataID: \.self) { item, _ in
19+
Color.blue
20+
.overlay(Text("\(item)"))
21+
}
22+
.layout {
23+
.grid(
24+
layoutMode: .adaptive(withMinItemSize: 100),
25+
itemSpacing: 5,
26+
lineSpacing: 5,
27+
itemSize: .absolute(50))
28+
}
29+
}
30+
}
31+
32+
// MARK: EXAMPLE 2
33+
34+
struct ExampleView: View
35+
{
36+
@State var dataExampleA = (0 ..< 21).map { $0 }
37+
@State var dataExampleB = (0 ..< 15).map { "ITEM \($0)" }
38+
39+
var body: some View
40+
{
41+
ASCollectionView
42+
{
43+
ASCollectionViewSection(
44+
id: 0,
45+
data: dataExampleA,
46+
dataID: \.self)
47+
{ item, _ in
48+
Color.blue
49+
.overlay(
50+
Text("\(item)")
51+
)
52+
}
53+
ASCollectionViewSection(
54+
id: 1,
55+
data: dataExampleB,
56+
dataID: \.self)
57+
{ item, _ in
58+
Color.green
59+
.overlay(
60+
Text("Complex layout - \(item)")
61+
)
62+
}
63+
.sectionHeader
64+
{
65+
Text("Section header")
66+
.padding()
67+
.frame(maxWidth: .infinity, alignment: .leading)
68+
.background(Color.yellow)
69+
}
70+
.sectionFooter
71+
{
72+
Text("This is a section footer!")
73+
.padding()
74+
}
75+
}
76+
.layout { sectionID in
77+
switch sectionID
78+
{
79+
default:
80+
return .grid(
81+
layoutMode: .adaptive(withMinItemSize: 100),
82+
itemSpacing: 5,
83+
lineSpacing: 5,
84+
itemSize: .absolute(50))
85+
}
86+
}
87+
}
88+
}
89+
90+
var sectionHeaderExample: ASCollectionViewSection<Int>
91+
{
92+
ASCollectionViewSection(id: 0) {
93+
Text("Cell 1")
94+
Text("Cell 2")
95+
}
96+
.sectionHeader
97+
{
98+
Text("Section header")
99+
.background(Color.yellow)
100+
}
101+
.sectionFooter
102+
{
103+
Text("Section footer")
104+
.background(Color.blue)
105+
}
106+
.sectionSupplementary(ofKind: "someOtherSupplementaryKindRequestedByYourLayout") {
107+
Text("Section supplementary")
108+
.background(Color.green)
109+
}
110+
}
111+
112+
// MARK: DecorationView Example
113+
114+
struct GroupBackground: View, Decoration
115+
{
116+
let cornerRadius: CGFloat = 12
117+
var body: some View
118+
{
119+
RoundedRectangle(cornerRadius: cornerRadius)
120+
.fill(Color(.secondarySystemGroupedBackground))
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)