Swift Format Text Field When User Is Typing

Swift format text field when user is typing

Is there a way I can recognise when the user is deleting and bypass the text field check?

The problem is that you've implemented the wrong method. Implement the delegate method text​Field(_:​should​Change​Characters​In:​replacement​String:​). This allows you distinguish where the text is changing (the second parameter is the range), and what the new text is — in the case of the backspace, replacementString will be empty.

Format text field as user is typing

You can use this code:

func currencyStringFromNumber(number: Double) -> String {
let formatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
formatter.currencyCode = NSLocale.currentLocale().displayNameForKey(NSLocaleCurrencySymbol, value: NSLocaleCurrencyCode)
return formatter.stringFromNumber(number)
}

let currencyString = currencyStringFromNumber(21010)
println("Currency String is: \(currencyString)")

// Will print $21,010.00

Here's a compilable and working example of this information extrapolated to work as you require.

import UIKit

class CurrencyTextFieldExample: UIViewController {

let currencyFormatter = NSNumberFormatter()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

let textField = UITextField()
textField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
textField.frame = CGRect(x: 0, y: 40, width: 320, height: 40)
textField.keyboardType = UIKeyboardType.NumberPad
textField.backgroundColor = UIColor.lightGrayColor()
self.view.addSubview(textField)

currencyFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
currencyFormatter.currencyCode = NSLocale.currentLocale().displayNameForKey(NSLocaleCurrencySymbol, value: NSLocaleCurrencyCode)

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func textFieldDidChange(textField: UITextField) {
var text = textField.text.stringByReplacingOccurrencesOfString(currencyFormatter.currencySymbol, withString: "").stringByReplacingOccurrencesOfString(currencyFormatter.groupingSeparator, withString: "").stringByReplacingOccurrencesOfString(currencyFormatter.decimalSeparator, withString: "")
textField.text = currencyFormatter.stringFromNumber((text as NSString).doubleValue / 100.0)
}

}

Let me know if you have questions.

How to apply format while typing UITextField

I don't think it is worthy to save the caret position when entering a credit card number (or login card). Just implement the deleteBackward method and remove the last digit. The user can always retype the numbers from left to right. I would also subclass textfield and create a custom field. So first remove all non digits from the field and then switch the number of digits left. If there is from 3 to 11 just insert the first hyphen. If there is 12 insert the first and second hyphens. If there is 13 add the third hyphen as well. Make sure to insert them in reverse other to make your life easier:

class LoginField: UITextField {
override func didMoveToSuperview() {
keyboardType = .numberPad
textAlignment = .center
autocorrectionType = .no
addTarget(self, action: #selector(editingChanged), for: .editingChanged)
}
override func deleteBackward() {
text?.removeAll(where: \.isDigit.negated)
let _ = text?.popLast()
sendActions(for: .editingChanged)
}
}


extension LoginField {
@objc func editingChanged(_ textField: UITextField) {
text?.removeAll(where: \.isDigit.negated)
text = text?.prefix(15).string
if let offset = text?.count,
let startIndex = text?.startIndex {
switch offset {
case 3...11:
if let index = text?.index(startIndex, offsetBy: 3) {
text?.insert("-", at: index)
}
case 12:
if let index = text?.index(startIndex, offsetBy: 12) {
text?.insert("-", at: index)
}

if let index = text?.index(startIndex, offsetBy: 3) {
text?.insert("-", at: index)
}
case 13...15:
if let index = text?.index(startIndex, offsetBy: 13) {
text?.insert("-", at: index)
}
if let index = text?.index(startIndex, offsetBy: 12) {
text?.insert("-", at: index)
}
if let index = text?.index(startIndex, offsetBy: 3) {
text?.insert("-", at: index)
}
default: break
}
}
}
}


extension Bool {
var negated: Bool { !self }
}


extension LosslessStringConvertible {
var string: String { .init(self) }
}


extension Character {
var isDigit: Bool { "0"..."9" ~= self }
}

How to format a textfield so when user inputs data its in format similar to 80/150?

You could do it this way, after setting self as the delegate:

let slash = "/"
let digits = CharacterSet(charactersIn: "0123456789")

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

//Deleting
if string.count == 0 {
var text = textField.text!
let start = text.startIndex
let beginRange = text.index(start, offsetBy: range.location)
let endRange = text.index(start, offsetBy: range.location + range.length)
text = String(text.prefix(upTo: beginRange))
+ String(text.suffix(from: endRange))
text = text.replacingOccurrences(of: "/", with: "")
if text.count >= 3 {
text = String(text.prefix(2)) + "/" + String(text.dropFirst(2))
}

textField.text = text

return false
}

//Typing

let count = textField.text!.count
guard string.count == 1,
count < 6,
let scalar = Character(string).unicodeScalars.first else {
return false
}

let isDigit = digits.contains(scalar)

switch count {
case 0, 3..<6 :
return isDigit
case 1:
if isDigit {
textField.text = textField.text! + string + "/"
}
return false
case 2:
if string == slash {
return true
} else {
textField.text = textField.text! + "/" + string
return false
}
default:
return false
}
}

This code works with the default keyboard too, and not just the numeric pad.

Add default text in textfield with follow of user typing value

Use this UITextField subclass, configure your postfix, and enjoy

improved

    class PostFixTextField: UITextField {

@IBInspectable var postfix : String = ""
@IBInspectable var removePostfixOnEditing : Bool = true

override init(frame: CGRect) {
super.init(frame: frame)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

override func awakeFromNib() {
super.awakeFromNib()
self.addTarget(self, action: #selector(textHasChanged), for: .editingDidEnd)
self.addTarget(self, action: #selector(removePostFix), for: .editingDidBegin)
self.addTarget(self, action: #selector(textHasChanged), for: .editingChanged)
}

func textHasChanged()
{
self.removePostFix()
self.addPostFix()
self.setCursorPosition(input: self, position: (self.originalText()?.characters.count)!)
}

private func setCursorPosition(input: UITextField, position: Int) {
let position = input.position(from: input.beginningOfDocument, offset: position)!
input.selectedTextRange = input.textRange(from: position, to: position)
}

func addPostFix()
{
if(self.text != nil)
{
self.text = self.text! + postfix
}
}

func originalText() ->String?{
let prefixRange = NSString(string: (self.attributedText?.string)!).range(of: postfix)
if(prefixRange.location != NSNotFound)
{
return self.text!.replacingOccurrences(of: postfix, with: "")
}
return self.text
}

func removePostFix(){

if(self.removePostfixOnEditing && self.text != nil)
{
self.text = self.originalText()
}
}
}

Hope this helps you

Append text to textfield while typing

First you need to import UITextFieldDelegate.

class myClass: UITextFieldDelegate

Then in viewDidload delegate your UITextFeild

textField.delegate = self //PUT the name of your textField

Then add this code also

textField.addTarget(self, action: "textFieldChanged:", forControlEvents: UIControlEvents.EditingChanged)

Then call this function

func textFieldChanged(textField: UITextField) {

if textfield.text != "" {
textfield.text = "\(self.enteredNumber) + LBS"
}
}

How do I format UITextField text in real time, while it's being edited?

Add a "textFieldDidChange" notification method to the text field control.

[textField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];

-(void)textFieldDidChange:(UITextField *)theTextField
{
NSLog(@"text changed: %@", theTextField.text);

NSString *textFieldText = [theTextField.text stringByReplacingOccurrencesOfString:@"," withString:@""];

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString *formattedOutput = [formatter stringFromNumber:[NSNumber numberWithInt:[textFieldText integerValue]]];
textField.text=formattedOutput;
}


Related Topics



Leave a reply



Submit