-
Notifications
You must be signed in to change notification settings - Fork 1
/
DatePickerProtocol.swift
163 lines (137 loc) · 5.48 KB
/
DatePickerProtocol.swift
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import UIKit
public protocol DatePickerProtocol: UIView {
/// Date picker mode
/// - `.date` – calendar to select date
/// - `.time` – wheel to select time
/// Default is `.date`
var mode: DatePickerMode { get set }
/// Minimum date available for selection (including)
/// If `nil`, then there is no limit
/// If the value is greater than `maximumDate`, both parameters are ignored
/// Default is `nil`
var minimumDate: Date? { get set }
/// Maximum date available for selection (including)
/// If `nil`, then there is no limit
/// If the value is less than `minimumDate`, both parameters are ignored
/// Default is `nil`
var maximumDate: Date? { get set }
/// Range of selected dates
/// If only one is selected, both bounds of the range are equal to the selected date (`date`)
/// If it is not equal to `nil`, the calendar is initialized on the month of the last date of the range,
/// otherwise on the month of the current date
/// Default is `nil`
var dateRange: ClosedRange<Date>? { get set }
/// Selected date
/// If a range is selected, it is equal to the first date of this range (`dateRange.lowerBound`)
/// Default is the current date
///
/// NOTE: The property is not optional for compatibility with `UIDatePicker`,
/// if you need optionality, use `dateRange`
var date: Date { get set }
var delegate: DatePickerDelegate? { get set }
var dataSource: DatePickerDataSource? { get set }
/// Date range selection
/// - Parameters:
/// - dateRange: new date range, `nil` removes the selection
/// - animated: selection with animation
func setDateRange(_ dateRange: ClosedRange<Date>?, animated: Bool)
/// Date selection
/// - Parameters:
/// - date: new date, `nil` removes the selection
/// - animated: selection with animation
func setDate(_ date: Date?, animated: Bool)
/// Reload information for all visible dates
/// using the delegate and the data source
func reloadAllDates()
}
/// Date picker mode
public enum DatePickerMode: Equatable {
/// Calendar to select date
case date(DatePickerDateModeSettings = .init())
/// Wheel to select time
case time(DatePickerTimeModeSettings = .init())
/// Calendar to select date
public static let date = DatePickerMode.date()
/// Wheel to select time
public static let time = DatePickerMode.time()
}
/// Date selection mode settings
public struct DatePickerDateModeSettings: Equatable {
/// Calendar layout direction
public enum LayoutDirection: Equatable {
/// Horizontal layout
/// Used when the component is part of a form,
/// or does not take up most of the screen
case horizontal
/// Vertical layout
/// Used when the component is the main one on the screen,
/// and takes up most of its space
case vertical
}
/// Date selection behavior
public enum SelectionBehavior: Equatable {
/// Single date selection
case single
/// Date range selection
case range(clampingBehavior: RangeClampingBehavior)
public static let range = SelectionBehavior.range(clampingBehavior: .untilFirstDisabled)
}
/// Date range clamping behavior
public enum RangeClampingBehavior: Equatable {
/// Do not clamp the selected range
case off
/// Clamp the selected range to the first available date
case untilFirstDisabled
}
/// Automatic selection of the current date
/// when initializing the calendar
public enum CurrentDateSelection: Equatable {
/// Select the current date
case on
/// Do not select the current date
case off
/// Automatic:
/// - `.on` for `selectionBehavior == .single`
/// - `.off` for `selectionBehavior == .range`
case automatic
}
/// Calendar layout direction
/// - `.horizontal` – horizontal
/// - `.vertical` – vertical
public let layoutDirection: LayoutDirection
/// Date selection behavior
/// - `.single` – single date selection
/// - `.range` – date range selection
/// Default is `.single`
public let selectionBehavior: SelectionBehavior
/// Highlights current date
/// Default is `true`
public let highlightsCurrentDate: Bool
/// Automatic selection of the current date
/// when initializing the calendar
/// - `.on` – select the current date
/// - `.off` – do not select the current date
/// - `.automatic` – select or not depending on `selectionBehavior`
/// Default is `.automatic`
public let currentDateSelection: CurrentDateSelection
public init(layoutDirection: LayoutDirection = .horizontal,
selectionBehavior: SelectionBehavior = .single,
highlightsCurrentDate: Bool = true,
currentDateSelection: CurrentDateSelection = .automatic) {
self.layoutDirection = layoutDirection
self.selectionBehavior = selectionBehavior
self.highlightsCurrentDate = highlightsCurrentDate
self.currentDateSelection = currentDateSelection
}
}
/// Time selection mode
public struct DatePickerTimeModeSettings: Equatable {
/// Interval on the minute wheel
/// Value must be a divisor of `60`
/// Minimum value is `1`, maximum is `30`
/// Default is `1`
public let minuteInterval: Int
public init(minuteInterval: Int = 1) {
self.minuteInterval = minuteInterval
}
}