Unexpected default kerning when using attributedText of UITextField - ios

I would like to create grouping with kerning in a UITextField. I use shouldChangeCharactersIn delegate method to be able to react to every text change. I format my text then assign it back to the attributedText property of the textfield. It works great but I have a small bug which I don't understand. When I leave the cursor after a character which has different kerning (lets say 4) then the default (around 1) and the textfield loses the focus that default kerning changes to the one which was before the cursor (4). Any idea why is this happening? How to solve this problem nicely?
I have noticed that if I nil out the property selectedTextRange in textFieldShouldEndEditing then this bug disappears but It just doesn't seem nice to implement this method just because of this.
Source code of this ViewController can be found here.

Related

UITextView responding unexpected to accessibility voice over

Currently I am walking through my whole iOS app to optimize it for accessibility voice over. When it comes to the UITextView, which I subclassed, voice over is not acting like I thought it would. My UITextView subclass is only changing a path's color on the superview's layer in becomeFirstResponder and resignFirstResponder. So nothing special on my UITextView subclass that could interfere with accessibility.
As long as there is no text in the UITextView it is acting as expected. Voiceover tells me that it is a text field and that I can double tap it to edit. But as soon as there is text in the UITextView, the only thing voice over tells me, is the value of the UITextView. Voice over doesn't tell me anymore that this is an editable text field.
Am I doing something wrong? Why is it acting like that?
I do appreciate any help!
If you didn't edit any accessibility hints or labels for the text field it should act accordingly. If selected it should say:
It is a text field
If you are editing it
The editing mode you are in
The value of the text field (nil if empty)
Where the cursor is
Then while you type it says the letters you are entering as you enter them. When you hit space or enter it should say the word you just typed. As long as your text field is exhibiting these behaviors you should be fine.
Tip: if you want to know how accessibility elements should act, try using a native iOS app with accessibility turned on and compare it with your app.

UITextField with partial edit

I want to use a UITextField so that only part of it will be editable.
I know about the delegation and shouldChangeCharactersInRange but for some reason, copying the ranged part is allowed.
My goal is to get similar result to this (the 'subject' text part) without being able to copy it.
Should i use a different UITextField with textFieldDidBeginEditing returning false all the time?
Is there a better solution?
In the screenshot, a UILabel placed next to the UITextField is used. I'd recommend doing this as it will give you more options when you decide to style the text.

iOS Text field delegate if the value of a text field is programatically

I have tried many an attempts to make this work. After much googling, trial & error, I post this here.
I have a text field whose value is changed when a slider near by is moved.
So in the IBAction sliderChanged, I have this
self.amountTextField.text = self.amountSlider.value
Now, I would like to be notified of this change in the text field value. I have tried with quite a few delegates. It so happens that when the text field's value is changed by tapping on the text field and changing it using the keyboard, these delegates are fired. But when the value is changed using the above piece of code, the delegates are not invoked.
I do like to know if theres a possible solution for this, i.e, i would like a delegate to handle the change in the text field value even if its done from code. Would love to have a working example. Thanks in advance.

Can you detect if a textfield has highlighted text

I was wondering if there was a way to detect if a textField.text is currently highlighted. I am trying to format a phone number, and it works under the exception that the user highlights the field, then starts typing a new number immediately instead of clearing it first. The first ( does not get set because i try to detect if the field is length 0 before adding it. On a text highlight, then keypress, the length is larger than 0 so it doesnt work.
thanks
Yes, since UITextField (and I believe UITextView) adopt the UITextInput protocol, you can send messages to those with any of that protocols methods, included selectedTextRange. See UITextInput Protocol Reference.

UITextFieldDelegate vs UITextField control events

If I want to handle changes to a UITextField, such as the user typing in it; it seems like this can be done either by assigning a delegate to that text field, and then having the delegate implement shouldChangeCharactersInRange, or by adding a target to the textField, and handling the UIControlEventEditingChanged event.
Aside from the fact that with the delegate method, you can return NO and therefor stop the user from making the edit, is there any difference between these 2 things?
Same question for handling the beginning of editing or the ending of editing. It could be done either with the appropriate delegate methods or with the appropriate events. What is the textField delegate actually for if the control events can do the necessary work?
shouldChangeCharactersInRange is called before a change occurs, and gives you opportunity to 'cancel' the change. UIControlEventEditingChanged is called after the change occurred.
You can determine the resulting value of the textField in shouldChangeCharactersInRange, but you have to manually apply the replacementString to the existing text, using the supplied range. (via NSString stringByReplacingCharactersInRange). If you want to know the resulting text, it's easier and more efficient to use UIControlEventEditingChanged.
shouldChangeCharactersInRange is often used to implement validation checking of input - that is, you can filter characters/pasted text as it is entered. If a field is for phone numbers, for example, you can return FALSE if the user types a non numeric character, or attempts to paste in text that isn't numeric.
You might find a case where you can reuse code for multiple controls if you can stick with the UIControlEvent-methods.
You're right; you can essentially do the same thing via both, but UIControl is lower level and lets you siphon off each particular UIEvent to different targets via [UIControl addTarget:action:forControlEvents:] where as there is only a single delegate.
I would also say that the UITextField delegate protocol is simply there as a more convenient, higher level alternative to UIControl/UIEvent as a way to manage the behaviour of a UITextField.
The most common delegate pattern is UITableView DataSource and Delegate and I would say that using the UITextField delegate protocol is quite similar and therefore looks far more straight forward with more defined intentions than handing the messages from UIControl directly.
One key difference I've found between the two approaches posed in the original question is that the delegate "shouldChangeCharactersInRange" gets called BEFORE the value in the UITextField changes. The target for UIControlEventEditingChanged gets called AFTER the value in the UITextField changes.
In the case that you're using these events to make sure (for example) that all fields in a dialog are completely filled in before enabling a "Done" button, the target approach may work better for you. It did for me.
The delegation approach is the way to homogenize UITextField and UITextView behavior.
UITextView does not have control events. In contrast, UITextFieldDelegate and UITextviewDelegate provide parallel methods.
I have found out that shouldChangeCharactersInRange passes the same NSRange for insertion and deletion of text. You append a space and then delete it, and the parameters from shouldChangeCharactersInRange are indistinguishable from duplication of the text.
So shouldChangeCharactersInRange actually cannot predict the resulting text.

Resources