检测空UITextField中的退格

mar*_*rcc 122 iphone uitextfield backspace ios

是否有办法检测何时在空白的iPhone键盘上按下Backspace/ DeleteUITextField?我想知道什么时候Backspace只有在UITextField空的情况下被按下.


根据@Alex Reynolds在评论中提出的建议,我在创建文本字段时添加了以下代码:

[[NSNotificationCenter defaultCenter] addObserver:self
          selector:@selector(handleTextFieldChanged:)
              name:UITextFieldTextDidChangeNotification
            object:searchTextField];
Run Code Online (Sandbox Code Playgroud)

收到此通知(handleTextFieldChanged调用函数),但Backspace在空字段中按键时仍然不会.有任何想法吗?


这个问题似乎有些混乱.我想在Backspace按下键时收到通知.而已.但是当解决方案UITextField已经空了时,解决方案也必须工作.

Jac*_*llo 142

斯威夫特4:


子类UITextField:

// MyTextField.swift
import UIKit

protocol MyTextFieldDelegate {
    func textFieldDidDelete()
}

class MyTextField: UITextField {

    var myDelegate: MyTextFieldDelegate?

    override func deleteBackward() {
        super.deleteBackward()
        myDelegate?.textFieldDidDelete()
    }

}
Run Code Online (Sandbox Code Playgroud)

执行:

// ViewController.swift

import UIKit

class ViewController: UIViewController, MyTextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // initialize textField
        let input = MyTextField(frame: CGRect(x: 50, y: 50, width: 150, height: 40))

        // set viewController as "myDelegate"
        input.myDelegate = self

        // add textField to view
        view.addSubview(input)

        // focus the text field
        input.becomeFirstResponder()
    }

    func textFieldDidDelete() {
        print("delete")
    }

}
Run Code Online (Sandbox Code Playgroud)

Objective-C的:


子类UITextField:

//Header
//MyTextField.h

//create delegate protocol
@protocol MyTextFieldDelegate <NSObject>
@optional
- (void)textFieldDidDelete;
@end

@interface MyTextField : UITextField<UIKeyInput>

//create "myDelegate"
@property (nonatomic, assign) id<MyTextFieldDelegate> myDelegate;
@end

//Implementation
#import "MyTextField.h"

@implementation MyTextField

- (void)deleteBackward {
    [super deleteBackward];

    if ([_myDelegate respondsToSelector:@selector(textFieldDidDelete)]){
        [_myDelegate textFieldDidDelete];
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

现在只需将MyTextFieldDelegate添加到您UIViewControllerUITextFields myDelegate并将其设置为self:

//View Controller Header
#import "MyTextField.h"

//add "MyTextFieldDelegate" to you view controller
@interface ViewController : UIViewController <MyTextFieldDelegate>
@end

//View Controller Implementation
- (void)viewDidLoad {
    //initialize your text field
    MyTextField *input = 
     [[MyTextField alloc] initWithFrame:CGRectMake(0, 0, 70, 30)];

    //set your view controller as "myDelegate"
    input.myDelegate = self;

    //add your text field to the view
    [self.view addSubview:input];
}

//MyTextField Delegate
- (void)textFieldDidDelete {
    NSLog(@"delete");
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的解决方案.接受的答案是黑客攻击.Objective C基于子类,该解决方案正确地使用它来解决问题. (9认同)
  • 这显然在ios8中不起作用,因为看起来像Apple Bug:https://devforums.apple.com/message/1045312#1045312 (4认同)
  • @FredClausen不适用于空文本字段 (2认同)
  • 我以你的名义捐款了。再次感谢! (2认同)

ma1*_*w28 40

更新:请参阅JacobCaraballo的答案以获取覆盖的示例-[UITextField deleteBackward].

签出UITextInput,特别是UIKeyInput有一个deleteBackward委托方法,当按下删除键时总是被调用.如果你正在做一些简单的事情,那么你可以考虑只是进行子类化UILabel并使其符合UIKeyInput协议,就像SimpleTextInput和这个iPhone UIKeyInput示例所做的那样.注意:UITextInput其亲属(包括UIKeyInput)仅适用于iOS 3.2及更高版本.

  • 这是正确的答案.使用UITextField的快速子类,它非常简单且非常简单. (2认同)

And*_*rew 34

这可能是一个长镜头,但它可以工作.尝试将文本字段的文本设置为零宽度空格字符\u200B.当在显示为空的文本字段上按下退格键时,它实际上会删除您的空间.然后你可以重新插入空间.

如果用户设法将插入符号移动到空格的左侧,则可能无法工作.

  • 如果用户设法将光标移动到空间的左侧,我可以确认未检测到删除.如果你能弄清楚如何修复它,那么你也应该继承`UITextField`并实现`canPerformAction:withSender:`为`select:`和`selectAll:`当文本等于字符串时返回NO` `@ "\ u200B"`. (6认同)
  • 对不起,但这个想法很糟糕.这是令人难以置信的hacky,不应该是30个左右的赞成票.我会将UITextField子类化,就像其他一些评论者所提到的那样. (6认同)
  • @Andrew,这是我决定采取的方法.它需要一些代码,但它确实有效.感谢您的帮助,而不是试图告诉我,我做错了什么. (3认同)
  • 这种技术可能适用于iPhone> 3.1.3,但它很黑,可能会破坏未来的版本等等.我想我找到了一个更清晰,更稳定的解决方案[如何在iPhone/iOS上检测删除键盘按键]( http://stackoverflow.com/questions/1977934/detect-backspace-in-uitextfield/6637821#6637821). (2认同)
  • 问题是这对安全测试字段不起作用.任何想法如何处理? (2认同)

小智 31

代码如下:

@interface MyTextField : UITextField
@end

@implementation MyTextField

- (void)deleteBackward
{
    [super deleteBackward];

    //At here, you can handle backspace key pressed event even the text field is empty
}

@end
Run Code Online (Sandbox Code Playgroud)

最后,忘记将文本字段的自定义类属性更改为"MyTextField"

  • 这应该是公认的答案.干净,实际上回答了这个问题. (5认同)
  • BJ Homer,93%的设备都在iOS 6上,所以不以iOS 5为目标通常不是什么大问题. (2认同)
  • 我很高兴我继续向下滚动以找到这个.100%正是今天在IOS 7中做到这一点的正确方法. (2认同)

Ruu*_*ser 18

Swift实现:

import UIKit

protocol PinTexFieldDelegate : UITextFieldDelegate {
    func didPressBackspace(textField : PinTextField)
}

class PinTextField: UITextField {

    override func deleteBackward() {
        super.deleteBackward()

        // If conforming to our extension protocol
        if let pinDelegate = self.delegate as? PinTexFieldDelegate {
            pinDelegate.didPressBackspace(self)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 17

我已经建立了比subclass解决方案更容易的其他方式.即使它有点奇怪,但它的工作正常.

- (BOOL)textView:(UITextView *)textView 
        shouldChangeTextInRange:(NSRange)range 
        replacementText:(NSString *)text
{
    const char * _char = [text cStringUsingEncoding:NSUTF8StringEncoding];
    int isBackSpace = strcmp(_char, "\b");

    if (isBackSpace == -8) {
       // is backspace
    }

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

比较结果有点奇怪-8.也许在某些方面我会错的C Programming.但它的正确工作;)

  • 仅当textView.text不为空时,此方法才有效. (4认同)
  • 这是一个`UITextViewDelegate` 方法,而不是`UITextFieldDelegate`。 (2认同)

小智 10

试试吧 delegate

- (BOOL)textField:(UITextField *)textField 
        shouldChangeCharactersInRange:(NSRange)range 
        replacementString:(NSString *)string {
Run Code Online (Sandbox Code Playgroud)

然后检查点击时是否range.length == 1是这种情况backspace.

  • 但是,只有当字段非空时才会调用.请注意原始问题.:) (8认同)

Pri*_*esh 10

请使用下面的代码,即使textfield为空,它也可以帮助您检测键盘删除键.

目标C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { return YES; }

斯威夫特:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { return true }
Run Code Online (Sandbox Code Playgroud)

  • Tx - 正是我所需要的。但它记录在哪里? (2认同)

Ben*_*all 8

Niklas Alvaeus的回答帮助我解决了类似的问题

我限制进入特定字符集,但它忽略了退格.所以我range.length == 1在修剪之前检查了一下NSString.如果是真的,我只是返回字符串而不修剪它.见下文

 - (BOOL) textField:(UITextField *)textField 
          shouldChangeCharactersInRange:(NSRange)range 
          replacementString:(NSString *)string
 {
     NSCharacterSet *nonNumberSet = 
      [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] 
         invertedSet];

    if (range.length == 1) {
       return string;
    }
    else {
       return ([string stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
    }   
 }
Run Code Online (Sandbox Code Playgroud)


Him*_*dia 5

是的,当textField为空时,使用下面的方法来检测退格.

需要添加UITextFieldDelegate

yourTextField.delegate = self (必须)

迅速:

func keyboardInputShouldDelete(_ textField: UITextField) -> Bool { 
    return true
}
Run Code Online (Sandbox Code Playgroud)

目标C:

- (BOOL)keyboardInputShouldDelete:(UITextField *)textField { 
    return YES; 
}
Run Code Online (Sandbox Code Playgroud)

  • 这甚至不需要我.所有其他委托方法都会在事件发生时被调用. (4认同)