forked from square/Listable
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathListReorderGesture.swift
More file actions
124 lines (102 loc) · 3.33 KB
/
Copy pathListReorderGesture.swift
File metadata and controls
124 lines (102 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
// ListReorderGesture.swift
// BlueprintUILists
//
// Created by Kyle Van Essen on 11/14/19.
//
import BlueprintUI
import ListableUI
import UIKit
///
/// An element that wraps your provided element, to enable support
/// for user-driven re-ordering in a list view.
///
/// If you do not support reordering items, you do not need
/// to add this element anywhere in your hierarchy.
///
/// This element on its own has no visual appearance. Thus, you should
/// still render your own reorder dragger / handle / etc in the passed in element.
///
/// In the below example, we see how to set up the content of a simple item, which contains
/// a text label and a reorder grabber.
///
/// ```
/// func element(with info : ApplyItemContentInfo) -> Element
/// {
/// Row { row in
/// row.add(child: Label(text: "..."))
///
/// row.add(child: ListReorderGesture(actions: info.actions, wrapping: MyReorderGrabber()))
///
/// // Could also be written as:
/// row.add(child: MyReorderGrabber().listReorderGesture(with: info.reorderingActions))
/// }
/// }
/// ```
public struct ListReorderGesture : Element
{
/// The element which is being wrapped by the reorder gesture.
public var element : Element
/// If the gesture is enabled or not.
public var isEnabled : Bool
let actions : ReorderingActions
/// Creates a new re-order gesture which wraps the provided element.
///
/// This element on its own has no visual appearance. Thus, you should
/// still render your own reorder dragger / handle / etc in the passed in element.
public init(
isEnabled : Bool = true,
actions : ReorderingActions,
wrapping element : Element
) {
self.isEnabled = isEnabled
self.actions = actions
self.element = element
}
//
// MARK: Element
//
public var content: ElementContent {
ElementContent(child: self.element)
}
public func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription?
{
return ViewDescription(View.self) { config in
config.builder = {
View(frame: context.bounds, wrapping: self)
}
config.apply { view in
view.recognizer.isEnabled = self.isEnabled
view.recognizer.apply(actions: self.actions)
}
}
}
}
public extension Element
{
/// Wraps the element in a re-order gesture.
func listReorderGesture(with actions : ReorderingActions, isEnabled : Bool = true) -> Element
{
ListReorderGesture(isEnabled: isEnabled, actions: actions, wrapping: self)
}
}
fileprivate extension ListReorderGesture
{
private final class View : UIView
{
let recognizer : ItemReordering.GestureRecognizer
init(frame: CGRect, wrapping : ListReorderGesture)
{
self.recognizer = .init()
super.init(frame: frame)
self.isOpaque = false
self.clipsToBounds = false
self.backgroundColor = .clear
self.addGestureRecognizer(self.recognizer)
}
@available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
listableFatal()
}
}
}