Skip to content

Commit c7a03b7

Browse files
author
Chris
authored
Merge pull request #4 from crelies/dev
4.0.0
2 parents 73cbabf + 5769a79 commit c7a03b7

File tree

3 files changed

+126
-17
lines changed

3 files changed

+126
-17
lines changed

README.md

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ private(set) lazy var pagination: AdvancedListPagination<AnyView, AnyView> = {
8585

8686
### 📁 Move and 🗑️ delete items
8787

88-
You can define which actions your list should support through the `onMoveAction` and `onDeleteAction` initializer parameters.
89-
**Per default the move and delete functions are disabled if you skip the parameters.**
88+
To enable the move or delete function just use the related `onMove` or `onDelete` view modifier.
89+
**Per default the functions are disabled if you don't add the view modifiers.**
9090

9191
```swift
9292
import AdvancedList
@@ -95,18 +95,20 @@ import AdvancedList
9595

9696
AdvancedList(yourData, content: { item in
9797
Text("Item")
98-
}, listState: $listState, onMoveAction: { (indexSet, index) in
99-
// do something
100-
}, onDeleteAction: { indexSet in
101-
// do something
102-
}, emptyStateView: {
98+
}, listState: $listState, emptyStateView: {
10399
Text("No data")
104100
}, errorStateView: { error in
105101
Text(error.localizedDescription)
106102
.lineLimit(nil)
107103
}, loadingStateView: {
108104
Text("Loading ...")
109105
}, pagination: .noPagination)
106+
.onMove { (indexSet, index) in
107+
// move me
108+
}
109+
.onDelete { indexSet in
110+
// delete me
111+
}
110112
```
111113

112114
### 🎛️ Filtering
@@ -217,3 +219,69 @@ AdvancedList(yourData, content: { item in
217219
Text("Loading ...")
218220
}, pagination: .noPagination)
219221
```
222+
223+
## Migration 3.0 -> 4.0
224+
225+
Thanks to a hint from @SpectralDragon I could refactor the `onMove` and `onDelete` functionality to view modifiers.
226+
227+
**Before:**
228+
```swift
229+
import AdvancedList
230+
231+
@State private var listState: ListState = .items
232+
233+
AdvancedList(yourData, content: { item in
234+
Text("Item")
235+
}, listState: $listState, onMoveAction: { (indexSet, index) in
236+
// move me
237+
}, onDeleteAction: { indexSet in
238+
// delete me
239+
}, emptyStateView: {
240+
Text("No data")
241+
}, errorStateView: { error in
242+
VStack {
243+
Text(error.localizedDescription)
244+
.lineLimit(nil)
245+
246+
Button(action: {
247+
// do something
248+
}) {
249+
Text("Retry")
250+
}
251+
}
252+
}, loadingStateView: {
253+
Text("Loading ...")
254+
}, pagination: .noPagination)
255+
```
256+
257+
**After:**
258+
```swift
259+
import AdvancedList
260+
261+
@State private var listState: ListState = .items
262+
263+
AdvancedList(yourData, content: { item in
264+
Text("Item")
265+
}, listState: $listState, emptyStateView: {
266+
Text("No data")
267+
}, errorStateView: { error in
268+
VStack {
269+
Text(error.localizedDescription)
270+
.lineLimit(nil)
271+
272+
Button(action: {
273+
// do something
274+
}) {
275+
Text("Retry")
276+
}
277+
}
278+
}, loadingStateView: {
279+
Text("Loading ...")
280+
}, pagination: .noPagination)
281+
.onMove { (indexSet, index) in
282+
// move me
283+
}
284+
.onDelete { indexSet in
285+
// delete me
286+
}
287+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// AnyDynamicViewContent.swift
3+
//
4+
//
5+
// Created by Christian Elies on 20.11.19.
6+
//
7+
8+
import SwiftUI
9+
10+
extension AdvancedList {
11+
struct AnyDynamicViewContent: DynamicViewContent {
12+
private let view: AnyView
13+
14+
private(set) var data: AnyCollection<Any>
15+
var body: some View { view }
16+
17+
init<View: DynamicViewContent>(_ view: View) {
18+
self.view = AnyView(view)
19+
self.data = AnyCollection(view.data.map { $0 as Any })
20+
}
21+
}
22+
}

Sources/AdvancedList/public/Views/AdvancedList.swift

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,28 @@ public struct AdvancedList<Data: RandomAccessCollection, Content: View, EmptySta
1313
public typealias OnMoveAction = Optional<(IndexSet, Int) -> Void>
1414
public typealias OnDeleteAction = Optional<(IndexSet) -> Void>
1515

16+
private typealias Configuration = (AnyDynamicViewContent) -> AnyDynamicViewContent
17+
1618
@ObservedObject private var pagination: AdvancedListPagination<PaginationErrorView, PaginationLoadingView>
1719
private var data: Data
1820
private var content: (Data.Element) -> Content
1921
private var listState: Binding<ListState>
20-
private var onMoveAction: OnMoveAction = nil
21-
private var onDeleteAction: OnDeleteAction = nil
2222
private let emptyStateView: () -> EmptyStateView
2323
private let errorStateView: (Error) -> ErrorStateView
2424
private let loadingStateView: () -> LoadingStateView
2525
@State private var isLastItem: Bool = false
2626

27-
public init(_ data: Data, @ViewBuilder content: @escaping (Data.Element) -> Content, listState: Binding<ListState>, onMoveAction: OnMoveAction = nil, onDeleteAction: OnDeleteAction = nil, @ViewBuilder emptyStateView: @escaping () -> EmptyStateView, @ViewBuilder errorStateView: @escaping (Error) -> ErrorStateView, @ViewBuilder loadingStateView: @escaping () -> LoadingStateView, pagination: AdvancedListPagination<PaginationErrorView, PaginationLoadingView>) {
27+
private var configurations: [Configuration]
28+
29+
public init(_ data: Data, @ViewBuilder content: @escaping (Data.Element) -> Content, listState: Binding<ListState>, @ViewBuilder emptyStateView: @escaping () -> EmptyStateView, @ViewBuilder errorStateView: @escaping (Error) -> ErrorStateView, @ViewBuilder loadingStateView: @escaping () -> LoadingStateView, pagination: AdvancedListPagination<PaginationErrorView, PaginationLoadingView>) {
2830
self.data = data
2931
self.content = content
3032
self.listState = listState
31-
self.onMoveAction = onMoveAction
32-
self.onDeleteAction = onDeleteAction
3333
self.emptyStateView = emptyStateView
3434
self.errorStateView = errorStateView
3535
self.loadingStateView = loadingStateView
3636
self.pagination = pagination
37+
configurations = []
3738
}
3839
}
3940

@@ -62,13 +63,31 @@ extension AdvancedList {
6263
}
6364
}
6465

66+
// MARK: - View modifiers
67+
extension AdvancedList {
68+
public func onMove(perform action: OnMoveAction) -> Self {
69+
configure { AnyDynamicViewContent($0.onMove(perform: action)) }
70+
}
71+
72+
public func onDelete(perform action: OnDeleteAction) -> Self {
73+
configure { AnyDynamicViewContent($0.onDelete(perform: action)) }
74+
}
75+
}
76+
77+
// MARK: - Private helper
6578
extension AdvancedList {
79+
private func configure(_ configuration: @escaping Configuration) -> Self {
80+
var result = self
81+
result.configurations.append(configuration)
82+
return result
83+
}
84+
6685
private func getListView() -> some View {
6786
List {
68-
ForEach(data) { item in
69-
self.getItemView(item)
70-
}.onMove(perform: self.onMoveAction)
71-
.onDelete(perform: self.onDeleteAction)
87+
configurations
88+
.reduce(AnyDynamicViewContent(ForEach(data) { item in
89+
self.getItemView(item)
90+
})) { (currentView, configuration) in configuration(currentView) }
7291
}
7392
}
7493

@@ -121,7 +140,7 @@ struct AdvancedList_Previews : PreviewProvider {
121140
let id: String = UUID().uuidString
122141
}
123142

124-
private static let items: [MockItem] = []
143+
private static let items: [MockItem] = Array(0...5).map { _ in MockItem() }
125144
@State private static var listState: ListState = .items
126145

127146
static var previews: some View {

0 commit comments

Comments
 (0)