@@ -30,6 +30,13 @@ public enum MaskAppearance {
30
30
}
31
31
}
32
32
33
+
34
+ /// How to choose format from `formats` property
35
+ public enum FormatSelectionStrategy {
36
+ case startFromCurrent
37
+ case startFromFirst
38
+ }
39
+
33
40
internal enum MaskState {
34
41
case mask
35
42
case input
@@ -53,10 +60,10 @@ internal enum ProcessAttributesResult {
53
60
}
54
61
55
62
public protocol FormattableInput : UITextInput {
63
+ var text : String ! { get set }
56
64
var currentFormat : String ? { get }
57
-
58
65
var formats : [ String ] { get set }
59
-
66
+ var formatSelectionStrategy : FormatSelectionStrategy { get set }
60
67
var maskAppearance : FormattableTextView . MaskAppearance { get set }
61
68
62
69
/// Allow inserting space character at the beginning of the text. It is required behavior in order to use iOS smart suggestions, e.g. telephone number.
@@ -67,16 +74,12 @@ public protocol FormattableInput: UITextInput {
67
74
68
75
/// Non-input symbols will be drawn with these attributes
69
76
var maskAttributes : [ NSAttributedString . Key : Any ] ! { get set }
70
-
71
77
var formatSymbols : [ Character : CharacterSet ] { get set }
72
-
73
78
var includeNonInputSymbolsAtTheEnd : Bool { get set }
74
79
75
80
/// x inset for input text and placeholders, may be set by user
76
81
var insetX : CGFloat { get set }
77
-
78
82
var keyboardType : UIKeyboardType { get set }
79
-
80
83
var formattedText : String { get }
81
84
82
85
func formatted( text: String ) -> NSAttributedString
@@ -90,6 +93,7 @@ internal protocol FormattableInputInternal: FormattableInput where Self: UIView
90
93
91
94
/// Non-input elements of format which will be drawn in separate layers
92
95
var maskLayers : [ Int : CALayer ] { get set }
96
+ var maskLayersTemp : [ Int : CALayer ] { get set }
93
97
var maskPlaceholders : [ CALayer ] { get set }
94
98
95
99
var backgroundColor : UIColor ? { get }
@@ -203,17 +207,30 @@ extension FormattableInputInternal {
203
207
}
204
208
205
209
func processAttributesForTextAndMask( range: NSRange , replacementText: String ) -> ProcessAttributesResult {
206
- var result = processAttributesForTextAndMaskInternal ( range: range, replacementText: replacementText, format: currentFormat)
207
- if case . allowed = result {
208
- return result
210
+ var result : ProcessAttributesResult = . withoutFormat
211
+ if case . startFromCurrent = self . formatSelectionStrategy {
212
+ result = processAttributesForTextAndMaskInternal ( range: range, replacementText: replacementText, format: currentFormat)
213
+ if case . allowed = result {
214
+ return result
215
+ }
209
216
}
210
217
for format in formats {
211
- if format == currentFormat { continue }
218
+ if case . startFromCurrent = self . formatSelectionStrategy, format == currentFormat {
219
+ continue
220
+ }
221
+ maskLayersTemp = maskLayers
222
+ maskLayers. removeAll ( )
212
223
result = processAttributesForTextAndMaskInternal ( range: range, replacementText: replacementText, format: format)
213
224
switch result {
214
225
case . notAllowed:
226
+ maskLayers = maskLayersTemp
227
+ maskLayersTemp. removeAll ( )
215
228
continue
216
229
default :
230
+ maskLayersTemp. values. forEach {
231
+ $0. removeFromSuperlayer ( )
232
+ }
233
+ maskLayersTemp. removeAll ( )
217
234
currentFormat = format
218
235
return result
219
236
}
0 commit comments