Skip to content

Commit

Permalink
fix mask layers on currentFormat change & add formatSelectionStrategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Motyzhenkov Mikhail committed Dec 17, 2021
1 parent c8ae648 commit eb8fc43
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
37 changes: 27 additions & 10 deletions FormattableTextView/FormattableInput.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ public enum MaskAppearance {
}
}


/// How to choose format from `formats` property
public enum FormatSelectionStrategy {
case startFromCurrent
case startFromFirst
}

internal enum MaskState {
case mask
case input
Expand All @@ -53,10 +60,10 @@ internal enum ProcessAttributesResult {
}

public protocol FormattableInput: UITextInput {
var text: String! { get set }
var currentFormat: String? { get }

var formats: [String] { get set }

var formatSelectionStrategy: FormatSelectionStrategy { get set }
var maskAppearance: FormattableTextView.MaskAppearance { get set }

/// 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.
Expand All @@ -67,16 +74,12 @@ public protocol FormattableInput: UITextInput {

/// Non-input symbols will be drawn with these attributes
var maskAttributes: [NSAttributedString.Key : Any]! { get set }

var formatSymbols: [Character : CharacterSet] { get set }

var includeNonInputSymbolsAtTheEnd: Bool { get set }

/// x inset for input text and placeholders, may be set by user
var insetX: CGFloat { get set }

var keyboardType: UIKeyboardType { get set }

var formattedText: String { get }

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

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

var backgroundColor: UIColor? { get }
Expand Down Expand Up @@ -203,17 +207,30 @@ extension FormattableInputInternal {
}

func processAttributesForTextAndMask(range: NSRange, replacementText: String) -> ProcessAttributesResult {
var result = processAttributesForTextAndMaskInternal(range: range, replacementText: replacementText, format: currentFormat)
if case .allowed = result {
return result
var result: ProcessAttributesResult = .withoutFormat
if case .startFromCurrent = self.formatSelectionStrategy {
result = processAttributesForTextAndMaskInternal(range: range, replacementText: replacementText, format: currentFormat)
if case .allowed = result {
return result
}
}
for format in formats {
if format == currentFormat { continue }
if case .startFromCurrent = self.formatSelectionStrategy, format == currentFormat {
continue
}
maskLayersTemp = maskLayers
maskLayers.removeAll()
result = processAttributesForTextAndMaskInternal(range: range, replacementText: replacementText, format: format)
switch result {
case .notAllowed:
maskLayers = maskLayersTemp
maskLayersTemp.removeAll()
continue
default:
maskLayersTemp.values.forEach {
$0.removeFromSuperlayer()
}
maskLayersTemp.removeAll()
currentFormat = format
return result
}
Expand Down
2 changes: 2 additions & 0 deletions FormattableTextView/FormattableKernTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ open class FormattableKernTextView: UITextView, FormattableInput, FormattableInp
processNonInputSymbolsAtTheEnd()
}
}
public var formatSelectionStrategy: FormatSelectionStrategy = .startFromCurrent

public internal(set) var currentFormat: String?

Expand Down Expand Up @@ -170,6 +171,7 @@ open class FormattableKernTextView: UITextView, FormattableInput, FormattableInp
}

internal var maskLayers = [Int: CALayer]()
internal var maskLayersTemp = [Int: CALayer]()

public var formatSymbols: [Character: CharacterSet] = ["d": CharacterSet.decimalDigits,
"w": CharacterSet.letters,
Expand Down
2 changes: 2 additions & 0 deletions FormattableTextView/FormattableTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ open class FormattableTextField: UITextField, FormattableInput, FormattableInput
processNonInputSymbolsAtTheEnd()
}
}
public var formatSelectionStrategy: FormatSelectionStrategy = .startFromCurrent

public internal(set) var currentFormat: String?

Expand Down Expand Up @@ -77,6 +78,7 @@ open class FormattableTextField: UITextField, FormattableInput, FormattableInput
}

internal var maskLayers = [Int: CALayer]()
internal var maskLayersTemp = [Int: CALayer]()
internal var maskPlaceholders = [CALayer]()

internal var formatInputChars: Set<Character>!
Expand Down
4 changes: 3 additions & 1 deletion FormattableTextViewExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ final class ViewController: UIViewController {
["dddd dddd dddd dddd"],
["wdddww dd"],
["+7 (ddd) ddd-dd-dd",
"+44 07ddd dddddd"],
"+44 dddddd ddd",
"+ddddddddddddddd"],
["dddddd ₽"]
]

Expand All @@ -58,6 +59,7 @@ final class ViewController: UIViewController {
tv.keyboardType = oldView.keyboardType
tv.backgroundColor = UIColor.white
tv.formats = formats[i]
tv.formatSelectionStrategy = .startFromFirst
tv.formatSymbols = ["d": CharacterSet.decimalDigits,
"0": CharacterSet(charactersIn: "0"),
"4": CharacterSet(charactersIn: "4"),
Expand Down

0 comments on commit eb8fc43

Please sign in to comment.