Running this:
@try
{
NSLog(@"1. autocapitalizationType = %d", [self.textField autocapitalizationType]);
NSLog(@"2. autocapitalizationType = %@", [self.textField valueForKey:@"autocapitalizationType"]);
}
@catch (NSException *exception)
{
NSLog(@"3. %@", exception);
}
Outputs this:
1. autocapitalizationType = 0
3. [<UITextField 0x6c15df0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key autocapitalizationType.
I was expecting:
1. autocapitalizationType = 0
2. autocapitalizationType = 0
This exception only happens with properties that are part of the UITextInputTraits
protocol. Regular properties of a UITextField
such has clearButtonMode
can be accessed through valueForKey:
.
So why can't you access UITextInputTraits
properties with key-value coding?
If you delve into the UIKit framework and open up UITextField.h
, you'll find:
@interface UITextField : UIControl <UITextInput, NSCoding> {
@private
UITextInputTraits *_traits;
UITextInputTraits *_nonAtomTraits;
You'll also find that clearButtonMode
is declared as a @property
in the UITextField header file, but that autocapitalizationType
(and the rest of the UITextInputTraits
protocol) are not.
You and I don't get to see UITextField.m
, so all we can really conclude is that Apple implemented the UITextField
's UITextInputTraits
protocol in a way that's not KVC compliant. Presumably glue code somewhere converts [myTextField autocapitalizationType]
into the appropriate value, but whatever behind-the-scenes magic is taking place stops short of valueForKey:
.
Here is my workaround: I swizzled valueForKey:
for every class implementing the textInputTraits
method. If the key is a UITextInputTraits key, then call valueForKey:
on the object's textInputTraits
instead of the object itself.
Here are the implementation details: 1, 2 and 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With