Skip to content

2.1 Affine Masks

Egor Taflanidi edited this page Jun 13, 2019 · 4 revisions

You may want to switch between mask formats depending on the input. Say, most of your phone numbers have their primary format like this:

+7 ([000]) [000] [00] [00]

But some of them may have an operator code:

+7 ([000]) [000] [00] [00]#[900]

Such that, when user starts to enter an operator code, the format is switched from the former to the latter.

Input                     Current Mask                        Complete

+7 (123) 456 78           +7 ([000]) [000] [00] [00]          False
+7 (123) 456 78 9         +7 ([000]) [000] [00] [00]          False
+7 (123) 456 78 90        +7 ([000]) [000] [00] [00]          True
+7 (123) 456 78 90#3      +7 ([000]) [000] [00] [00]#[900]    False
+7 (123) 456 78 90#33     +7 ([000]) [000] [00] [00]#[900]    True
+7 (123) 456 78 90#333    +7 ([000]) [000] [00] [00]#[900]    True

Put your additional formats into the affineFormats property:

open class ViewController: UIViewController, MaskedTextFieldDelegateListener {
    @IBOutlet weak var listener: MaskedTextFieldDelegate!
    
    open override func viewDidLoad() {
        super.viewDidLoad()
        listener.affinityCalculationStrategy = .prefix
        listener.affineFormats = [
            "+7 ([000]) [000] [00] [00]#[900]"
        ]
    }    
}

— same works for MaskedTextInputListener and MaskedTextViewDelegate objects.

Affinity calculation strategy

Affinity is an integer number, which represents the similarity between the input and the current mask. Thus, the mask with the highest affinity is picked to format the output.

Affinity calculation strategy is a text field listener property allowing to alter the math behind the affinity calculation.

.wholeString

is the default affinity calculation strategy.
With this strategy, affinity equals text length subtracting the count of all added and removed characters.

For example:

format: [00].[00]

input1: 1234
input2: 12.34
input3: 1.234

affinity1 = 4 (symbols) - 1 (missed dot)                       = 3
affinity2 = 5 (symbols)                                        = 5
affinity3 = 5 (symbols) - 1 (superfluous dot) - 1 (missed dot) = 3

.prefix

— this configuration works better when your affine formats have distinctive prefixes, e.g. +1 ( and 8 ( in phone numbers.
With this strategy, affinity equals length of the longest common prefix between the input and the output.

For example:

format1: +7 [000] [000]
format2: 8 [000] [000]

input: +7 12 345
affinity1 = 5
affinity2 = 0

input: 8 12 345
affinity1 = 0
affinity2 = 4

.capacity

— this strategy comes in handy when the mask format radically changes depending on the input length.
With this strategy, affinity equals tolerance between the length of the input and the total amount of text current mask can accommodate.

For example:

format1: [00]-[0]
format2: [00]-[000]
format3: [00]-[00000]

input          affinity1          affinity2    affinity3
1              -3                 -5           -7
12             -2                 -4           -6
123            -1                 -3           -5
12-3           0                  -2           -4
1234           0                  -2           -4
12345          Int.min.           -1           -3
123456         Int.min.           0            -2

IMPORTANT: Make sure the primary mask format of your text field listener is assigned to the widest available mask format when using this affinity calculation strategy.

.extractedValueCapacity

— this strategy comes in handy when the mask format radically changes depending on the extracted value length.
With this strategy, affinity equals tolerance between the length of the extracted value and the total value length current mask can accommodate.

For example:

format1: [00]-[0]
format2: [00]-[000]
format3: [00]-[00000]

input          affinity1          affinity2          affinity3
1              -2                 -4                 -6
12             -1                 -3                 -5
123            0                  -2                 -4
12-3           0                  -2                 -4
1234           Int.min            -1                 -3
12345          Int.min            0                  -2
123456         Int.min            Int.min            -1

IMPORTANT: Make sure the primary mask format of your text field listener is assigned to the widest available mask format when using this affinity calculation strategy.