【问题标题】:UItextView delegate not called using custom keyboard未使用自定义键盘调用 UItextView 委托
【发布时间】:2012-11-09 00:13:46
【问题描述】:

我有几个 UITextView 子视图,都使用相同的自定义输入界面(基本上是带有自动填充选项和保存按钮的数字键盘)。

我的问题是委托方法 shouldChangeCharactersInRange: 在从我的自定义键盘修改文本字段的文本时不会被调用(在将文本从剪贴板粘贴到文本字段以及使用标准数字键盘时它确实有效)。文本字段的文本会更改,但不会调用防止无效条目的委托方法。其他样式 DidBeginEditing: 的委托方法总是被调用。

尽管在SO LINK 中说了什么,documentation 声明将调用 shouldChangeCharactersInRange: 委托方法:“每当用户键入新字符或删除现有字符时,文本视图都会调用此方法。”

我错过了什么?

相关代码部分:

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
..

【问题讨论】:

    标签: iphone ios uitextfield uitextfielddelegate


    【解决方案1】:

    这一行:

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

    不会导致调用textField:shouldChangeCharactersInRange:replacementString:。这是你所期待的吗?

    由于您明确更改文本字段的文本,因此不会进行“键入”。

    让您的自定义键盘更新文本字段的正确方法是调用“insertText:”方法。此方法将正确处理任何选择、移动光标和调用委托方法。

    编辑:您可能希望查看my answer here 以获得完整的自定义键盘设置(减去实际按钮)。

    【讨论】:

    • 嗨 rmaddy,我刚刚尝试了 insertText: 方法,但结果还是一样。我的委托方法仅在粘贴时调用,从粘贴板上剪切文本,但在从键盘输入时不调用。我也采用了您的键盘(以这种方式追踪第一响应者的好主意!),但仍然没有改善。未调用 textField:shouldChangeCharactersInRange:replacementString:。最后我使用here描述的方法,但这正是我想要的。
    • 对不起,你是对的。我本可以发誓它在我自己的应用程序中被调用,但我只是加倍检查 - 它不是。看起来我需要更新我的代码以在调用 insertText 之前显式调用委托方法。
    • 我也试过这个。这并不容易,因为您需要知道光标在哪里以及是否标记了文本以填充 NSRange 参数,但是 UITextField.selectedTextRange 是 UITextRange 类型,它由两个 UITextPosition (start, end) 组成,这是一个抽象类。我找不到将其转换为 NSRange 的方法。
    • 我在其他答案中更新了代码。更新后的代码现在可以正确处理调用“shouldChange”方法。看看吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 2021-08-29
    相关资源
    最近更新 更多