Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add livedata twoway bindings with text formatting #142

Open
Alex009 opened this issue Jun 22, 2021 · 0 comments
Open

Add livedata twoway bindings with text formatting #142

Alex009 opened this issue Jun 22, 2021 · 0 comments
Labels
enhancement New feature or request

Comments

@Alex009
Copy link
Member

Alex009 commented Jun 22, 2021

Now we implement textformatting support inside project, but we can implement support of formatting out of box.
for example with integration of https://github.com/redmadrobot/input-mask-android and https://github.com/redmadrobot/input-mask-ios as we do inside our projects.

or with https://github.com/artemkrachulov/AKMaskField on iOS

or by custom code:

import Foundation
import UIKit

class DefaultTextFormatter: NSObject {
    
    public let textPattern: String
    
    /// Symbol that will be replace by input symbols
    public let patternSymbol: Character
    
    public init(textPattern: String,
                patternSymbol: Character = "#") {
        self.textPattern = textPattern
        self.patternSymbol = patternSymbol
    }
    
    func format(_ unformattedText: String?) -> String? {
        guard let unformattedText = unformattedText else { return nil }
        var formatted = String.init()
        var unformattedIndex = 0
        var patternIndex = 0
        
        while patternIndex < textPattern.count && unformattedIndex < unformattedText.count {
            guard let patternCharacter = textPattern.characterAt(patternIndex) else { break }
            if patternCharacter == patternSymbol {
                if let unformattedCharacter = unformattedText.characterAt(unformattedIndex) {
                    formatted.append(unformattedCharacter)
                }
                unformattedIndex += 1
            } else {
                formatted.append(patternCharacter)
            }
            patternIndex += 1
        }
        return formatted
    }
    
    func unformat(_ formatted: String?) -> String? {
        guard let formatted = formatted else { return nil }
        
        if textPattern.starts(with: formatted) {
            return formatted
        }
        var unformatted = String()
        var formattedIndex = 0
        
        while formattedIndex < formatted.count {
            if let formattedCharacter = formatted.characterAt(formattedIndex) {
                if formattedIndex >= textPattern.count {
                    unformatted.append(formattedCharacter)
                } else if formattedCharacter != textPattern.characterAt(formattedIndex) {
                    unformatted.append(formattedCharacter)
                }
                formattedIndex += 1
            }
        }
        return unformatted
    }
}

extension DefaultTextFormatter: UITextFieldDelegate {
    func textField(
        _ textField: UITextField,
        shouldChangeCharactersIn range: NSRange,
        replacementString string: String
    ) -> Bool {
        let newText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
        let unformattedText = unformat(newText)
        
        // Обход проблемы, когда юзер начинает ввод с символа, с которого начинается паттерн
        // (не возможно было начать ввод с 8)
        if textPattern.starts(with: newText ?? "") {
            textField.text = newText
        } else {
            textField.text = format(unformattedText)?.uppercased()
        }
        
        textField.sendActions(for: UIControl.Event.editingChanged)
        return false
    }
}
@Alex009 Alex009 added the enhancement New feature or request label Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: No status
Development

No branches or pull requests

1 participant