Skip to content

Commit eb8fc43

Browse files
author
Motyzhenkov Mikhail
committed
fix mask layers on currentFormat change & add formatSelectionStrategy
1 parent c8ae648 commit eb8fc43

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed

FormattableTextView/FormattableInput.swift

+27-10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ public enum MaskAppearance {
3030
}
3131
}
3232

33+
34+
/// How to choose format from `formats` property
35+
public enum FormatSelectionStrategy {
36+
case startFromCurrent
37+
case startFromFirst
38+
}
39+
3340
internal enum MaskState {
3441
case mask
3542
case input
@@ -53,10 +60,10 @@ internal enum ProcessAttributesResult {
5360
}
5461

5562
public protocol FormattableInput: UITextInput {
63+
var text: String! { get set }
5664
var currentFormat: String? { get }
57-
5865
var formats: [String] { get set }
59-
66+
var formatSelectionStrategy: FormatSelectionStrategy { get set }
6067
var maskAppearance: FormattableTextView.MaskAppearance { get set }
6168

6269
/// 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 {
6774

6875
/// Non-input symbols will be drawn with these attributes
6976
var maskAttributes: [NSAttributedString.Key : Any]! { get set }
70-
7177
var formatSymbols: [Character : CharacterSet] { get set }
72-
7378
var includeNonInputSymbolsAtTheEnd: Bool { get set }
7479

7580
/// x inset for input text and placeholders, may be set by user
7681
var insetX: CGFloat { get set }
77-
7882
var keyboardType: UIKeyboardType { get set }
79-
8083
var formattedText: String { get }
8184

8285
func formatted(text: String) -> NSAttributedString
@@ -90,6 +93,7 @@ internal protocol FormattableInputInternal: FormattableInput where Self: UIView
9093

9194
/// Non-input elements of format which will be drawn in separate layers
9295
var maskLayers: [Int: CALayer] { get set }
96+
var maskLayersTemp: [Int: CALayer] { get set }
9397
var maskPlaceholders: [CALayer] { get set }
9498

9599
var backgroundColor: UIColor? { get }
@@ -203,17 +207,30 @@ extension FormattableInputInternal {
203207
}
204208

205209
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+
}
209216
}
210217
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()
212223
result = processAttributesForTextAndMaskInternal(range: range, replacementText: replacementText, format: format)
213224
switch result {
214225
case .notAllowed:
226+
maskLayers = maskLayersTemp
227+
maskLayersTemp.removeAll()
215228
continue
216229
default:
230+
maskLayersTemp.values.forEach {
231+
$0.removeFromSuperlayer()
232+
}
233+
maskLayersTemp.removeAll()
217234
currentFormat = format
218235
return result
219236
}

FormattableTextView/FormattableKernTextView.swift

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ open class FormattableKernTextView: UITextView, FormattableInput, FormattableInp
9898
processNonInputSymbolsAtTheEnd()
9999
}
100100
}
101+
public var formatSelectionStrategy: FormatSelectionStrategy = .startFromCurrent
101102

102103
public internal(set) var currentFormat: String?
103104

@@ -170,6 +171,7 @@ open class FormattableKernTextView: UITextView, FormattableInput, FormattableInp
170171
}
171172

172173
internal var maskLayers = [Int: CALayer]()
174+
internal var maskLayersTemp = [Int: CALayer]()
173175

174176
public var formatSymbols: [Character: CharacterSet] = ["d": CharacterSet.decimalDigits,
175177
"w": CharacterSet.letters,

FormattableTextView/FormattableTextField.swift

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ open class FormattableTextField: UITextField, FormattableInput, FormattableInput
3232
processNonInputSymbolsAtTheEnd()
3333
}
3434
}
35+
public var formatSelectionStrategy: FormatSelectionStrategy = .startFromCurrent
3536

3637
public internal(set) var currentFormat: String?
3738

@@ -77,6 +78,7 @@ open class FormattableTextField: UITextField, FormattableInput, FormattableInput
7778
}
7879

7980
internal var maskLayers = [Int: CALayer]()
81+
internal var maskLayersTemp = [Int: CALayer]()
8082
internal var maskPlaceholders = [CALayer]()
8183

8284
internal var formatInputChars: Set<Character>!

FormattableTextViewExample/ViewController.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ final class ViewController: UIViewController {
3131
["dddd dddd dddd dddd"],
3232
["wdddww dd"],
3333
["+7 (ddd) ddd-dd-dd",
34-
"+44 07ddd dddddd"],
34+
"+44 dddddd ddd",
35+
"+ddddddddddddddd"],
3536
["dddddd ₽"]
3637
]
3738

@@ -58,6 +59,7 @@ final class ViewController: UIViewController {
5859
tv.keyboardType = oldView.keyboardType
5960
tv.backgroundColor = UIColor.white
6061
tv.formats = formats[i]
62+
tv.formatSelectionStrategy = .startFromFirst
6163
tv.formatSymbols = ["d": CharacterSet.decimalDigits,
6264
"0": CharacterSet(charactersIn: "0"),
6365
"4": CharacterSet(charactersIn: "4"),

0 commit comments

Comments
 (0)