Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UItextView delegate not called using custom keyboard

I have several UITextView subviews, all using the same custom input interface (basically a numberpad with an autofill-option and a save button).

My problem is that the delegate method shouldChangeCharactersInRange: is not called when the textfield's text is modified from my custom keyboard (it does work when pasting text from clipboard into the textfields and also when using the standard numberpad keyboard). The text of the textfields change, but the delegate method to prevent invalid entries is not called. Other delegate methods of style DidBeginEditing: are called always.

despite of what is said in this SO LINK the documentation states that the shouldChangeCharactersInRange: delegate method will be called: "The text view calls this method whenever the user types a new character or deletes an existing character."

What am I missing?

relevant code parts:

ViewController.h:

@interface ManualPositionViewController : UIViewController <UITextFieldDelegate> {
    LocationEntryTextField *latitude;
}
@property (nonatomic, retain) IBOutlet LocationEntryTextField *latitude;
@property (nonatomic, retain) IBOutlet LocationKeyboard *locationKeyboard;
..

ViewController.m:

@synthesize latitude;
@synthesize locationKeyboard;
self.latitude.inputView = locationKeyboard;
self.latitude.delegate = self;

- (void)textFieldDidBeginEditing:(LocationEntryTextField *)aTextField {

    NSLog(@"textFieldDidBeginEditing called!");
    self.locationKeyboard.currentTextfield = aTextField;
}

- (BOOL)textField:(LocationEntryTextField *)editedTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)replacementString {

    NSLog(@"shouldChangeCharactersInRange called!");
    NSCharacterSet *decimalSet = [NSCharacterSet decimalDigitCharacterSet];

    if ([[replacementString stringByTrimmingCharactersInSet:decimalSet] isEqualToString:@""]) { 
        NSLog(@"Result: YES");
        return YES;
    }
    else {
        NSLog(@"Result: NO");           
        return NO;
    }
}

LocationKeyboard.h:

#import <UIKit/UIKit.h>
#import "LocationEntryTextField.h"

@interface LocationKeyboard : UIView {
    LocationEntryTextField  *currentTextfield; // track first responder
}
@property (weak) LocationEntryTextField *currentTextfield;
- (IBAction) numberButtonPressed:(UIButton*)sender;
- (IBAction) backspaceButtonPressed:(UIButton*)sender;
@end

- (IBAction) numberButtonPressed:(UIButton*)sender {
    NSString *entryString = @"test";
    [self.currentTextfield replaceRange:self.currentTextfield.selectedTextRange withText:entryString];
}

LocationEntryTextField.h:

@interface LocationEntryTextField : UITextField
..
like image 376
user1702623 Avatar asked Feb 18 '23 13:02

user1702623


1 Answers

This line:

[self.currentTextfield replaceRange:self.currentTextfield.selectedTextRange withText:entryString];

doesn't result in a call to textField:shouldChangeCharactersInRange:replacementString:. Is that what you are expecting?

Since you are explicitly changing the text of the text field, there is no "typing" going on.

The proper way to have your custom keyboard update the text field is to call the 'insertText:` method. This method will properly deal with any selection, moving the cursor, and calling delegate methods.

Edit: You may wish to look at my answer here for a complete custom keyboard setup (minus the actual buttons).

like image 165
rmaddy Avatar answered Mar 03 '23 03:03

rmaddy