Arjen Hiemstra
Arjen Hiemstra

Reputation: 179

Unexpected behaviour text textFieldShouldBeginEditing / textFieldDidBeginEditing

I have a UItextField called textField on a static cell tableView. That field contains a currency amount - like "$10,000.00".

When editing that amount, the currency and thousand grouping symbols are a bit in the way. Therefore I would like to remove those when the field becomes the first responder.

I do this in textFieldShouldBeginEditing.

The first time I do this, everything works. The textField's contents are reformatted without currency and thousand group separator.

On textFieldDidEndEditing I re-format the value into a proper currency string again. This also works.

The problem happens when I re-enter the field for a 2nd time. While debugging I can see the textField.text has changed into the string without currency symbol and grouping symbol, but the display does not show that. Although it did work the first time! The 2nd time it looks like there is a mismatch between what is on the screen and what value the debugger sees.

I've tried things like:

... but this does not work.

So I copied the code that removes the currency formatting in textFieldShouldBeginEditing to a new delegate method textFieldDidBeginEditing.

Then everything worked fine. I could tap other controls and back to the textField a number of times and each time the control would lose its formatting when entered and would be restored to a formatted currency string after losing focus.

So I decided to delete the method textFieldShouldBeginEditing. But then things broke down again! It looks like I have to implement both textFieldShouldBeginEditing as well as textFieldDidBeginEditing to be able to prepare a textField's contents for user-editing?

Is this a bug?

extension Double {
    public func doubleToString(numberStyle: NumberFormatter.Style, decimals: Int, withThousandSeparator: Bool) -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = numberStyle
        numberFormatter.maximumFractionDigits = decimals
        if !withThousandSeparator {
            numberFormatter.groupingSeparator = ""
        }
        return numberFormatter.string(from: NSNumber(value: self)) ?? ""
    }
}

func textFieldDidBeginEditing(_ textField: UITextField) {
    if textField === self.textField {
        textField.text = amount.doubleToString(numberStyle: .decimal, decimals: 2, withThousandSeparator: false)
    }
}

Upvotes: 1

Views: 87

Answers (1)

Shruti Thombre
Shruti Thombre

Reputation: 988

You should try textField's text changed event, attaching code below :

Add target on textField for text changed :

self.textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)

Function for textField's text change :

func textFieldDidChange(_ textField: UITextField)
{
    if textField === self.textField
    {
         //try formatting here
    }
}

Upvotes: 1

Related Questions