ToddK
ToddK

Reputation: 1

UITextFieldDelegate problem

I have an iPad app using the UITextFieldDelegate protocol. I declare and implement the full protocol. The field calling this protocol is declared as follows:

typingInput = [ [ [ UITextField alloc ] initWithFrame: textIn ] retain ];
dp.x = center.x;
dp.y = center.y - 42;
typingInput.center = dp;

[ self addSubview: typingInput ];
[ typingInput release ];

typingInput.font = [ UIFont systemFontOfSize: 52.0 ];
[ typingInput setTextColor: [ UIColor whiteColor ] ];
typingInput.backgroundColor = [ UIColor colorWithWhite: 0.0 alpha: 0.0 ];
typingInput.alpha = 0.0;
typingInput.userInteractionEnabled = NO;
[ typingInput addTarget: self action: @selector(textField:shouldChangeCharactersInRange:replacementString:) forControlEvents: UIControlEventEditingChanged | UIControlEventAllEditingEvents  ];
typingInput.text = @"";
typingInput.autocorrectionType = UITextAutocorrectionTypeNo;
typingInput.enablesReturnKeyAutomatically = YES;
typingInput.delegate = self;

The issue is with

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange: (NSRange)qrange replacementString: (NSString *)str;

On the simulator the run-time type of 'str' either is nil or NSCFString according to this:

NSLog(@"class = %@, value='%@'", [ str class ], str );

Everything works fine when I edit the string.

On the iPad the same logging statement returns:

class = UIFieldEditor, value='<UIFieldEditor: 0xb5f400; frame = (0 0; 640 640); text = 'Foobar'; opaque = NO; layer = <UIWebLayer: 0x113ba0>>'

Subsequent uses of 'str' as an NSString causes a crash on the iPad when I attempt to add, change or delete text. qrange is also invalid (length is some huge number).

UIFieldEditor is part of UIWebView.h which I am not using.

To some extent changing the declaration of the protocol members affects the behavior.

Since I cannot find anyone else with this problem I have to assume I am doing something wrong.

Any ideas?

Upvotes: 0

Views: 1316

Answers (1)

user467105
user467105

Reputation:

The shouldChangeCharactersInRange delegate method will automatically be called by the UITextField (by having set its delegate property). The UITextField may also call other delegate methods if you've implemented them.

You do not (and should not) explicitly connect delegate methods to a UITextField event using addTarget. This will result in the delegate method getting called twice (once as defined by the protocol and second by your addTarget).

By (wrongly) connecting a UIControl event to that method, it gets called with parameters that don't match up with the method's parameters. UIControl event handling methods (which shouldChangeCharactersInRange is not) have these forms:

- (void)methodName;
- (void)methodName:(id)sender;
- (void)methodName:(id)sender withEvent:(UIEvent *)event;

See Cocoa Target-Action and iPhone App Development Lecture 4 for details.

Remove the addTarget line to fix.


Separately:

  • isn't setting the alpha to 0.0 making the control invisible?
  • why is userInteractionEnabled set to NO?
  • explicitly calling retain, calling addSubView, calling release, and then setting properties (even if it works) isn't the usual way of doing things. Remove the retain and move the addSubView and release to the end.

Upvotes: 1

Related Questions