我已经将UITextField子类化,并实现了UIKeyInput协议的deleteBackward方法来检测被按下的退格。这适用于iOS 7,但不适用于iOS 8。
当我按退格键时,不再在UITextField上调用deleteBackward。
我已经检查了文档和发行说明,没有任何指出可能发生这种情况的原因。有什么指针吗?
答案 0 :(得分:47)
许多人一直在说这是一个错误,但由于这个问题仍然存在于GM中,我开始认为它可能是逻辑上的变化。话虽如此,我为我的应用程序编写了这段代码,并在iOS 7-8上进行了测试。
将以下方法添加到UITextField
子类。
- (BOOL)keyboardInputShouldDelete:(UITextField *)textField {
BOOL shouldDelete = YES;
if ([UITextField instancesRespondToSelector:_cmd]) {
BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];
if (keyboardInputShouldDelete) {
shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
}
}
BOOL isIos8 = ([[[UIDevice currentDevice] systemVersion] intValue] == 8);
BOOL isLessThanIos8_3 = ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3f);
if (![textField.text length] && isIos8 && isLessThanIos8_3) {
[self deleteBackward];
}
return shouldDelete;
}
此代码稍微位于私有API的红线之前,但是使用它时应该没有问题。我的应用程序使用此代码在应用程序商店中。
为了解释一下,正在调用此方法的超级实现以避免丢失代码。如果没有文本且iOS版本介于8-8.2之间,则打电话给-deleteBackward
。
编辑:2015年1月22日
继承子类-deleteBackward
的{{1}}方法也可能有所帮助。这修复了一些有条件的错误。一种是如果你使用自定义键盘。这是该方法的一个例子。
UITextField
编辑:4/13/15
正如@ Gee.E评论的那样,iOS 8.3解决了这个问题。代码已更新以反映更改。
答案 1 :(得分:22)
您可以通过实现UITextField委托方法来检测用户何时使用退格键删除文本:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (range.length==1 && string.length==0)
NSLog(@"backspace tapped");
return YES;
}
答案 2 :(得分:12)
你必须在github上查看MBContactPicker的示例。通过我测试的iOS8上的Backspace按钮删除MBContactPicker上的联系人。而且效果很好!您可以使用它作为示例。
MBContactPicker的作者使用next方法:当UITextField必须为空时(或者在它为空时调用becomeFirstResponder之前),他在那里保存单个空格符号。然后当您按Backspace按钮时(当焦点设置为UITextField的文本结尾时),方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
会奏效。在里面你必须使用这样的支票:
NSString *resultString = [textField.text stringByReplacingCharactersInRange:range withString:string];
BOOL isPressedBackspaceAfterSingleSpaceSymbol = [string isEqualToString:@""] && [resultString isEqualToString:@""] && range.location == 0 && range.length == 1;
if (isPressedBackspaceAfterSingleSpaceSymbol) {
// your actions for deleteBackward actions
}
因此,您必须始终控制UITextField包含单个空格。
这不是黑客攻击。因此,用户不会注意到某些行为已被更改
答案 3 :(得分:5)
在iOS8中,一些自定义键盘会删除整个单词,所以只检查string.length就可以了。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (string.length==0) { //Delete any cases
if(range.length > 1){
//Delete whole word
}
else if(range.length == 1){
//Delete single letter
}
else if(range.length == 0){
//Tap delete key when textField empty
}
}
return YES;
}
答案 4 :(得分:5)
Swift 2.2:
filters: [
{
property: 'type',
operator: '=',
value: 'recorder'
},
{
property: 'number',
operator: '=',
value: '{number.value}'
}
答案 5 :(得分:1)
用于检测基于BackSpace的删除的Swift 2.0版本,referencing code post from almas
//For Detecting Backspace based Deletion of Entire Word in TextField
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (range.length == 1 && string.isEmpty){
print("Used Backspace")
}
return true
}
答案 6 :(得分:1)
这并没有明确回答原始问题,但是对textField(_:shouldChangeCharactersIn:replacementString:)
的文档来说毫无价值,它说:
“ string
:指定范围的替换字符串。在键入过程中,此参数通常仅包含键入的单个新字符,但是如果用户要粘贴文本,则它可能包含更多字符。删除一个或多个字符,替换字符串为空。”
因此,如果实现UITextFieldDelegate
,我们可以检测到textField(_:shouldChangeCharactersIn:replacementString:)
中的退格键,并检查string
的长度是否为0。
这里的许多其他答案都使用了相同的逻辑,而没有引用文档,因此希望从源头上正确地使它使人们更习惯使用它。
答案 7 :(得分:0)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding];
int isBackSpace = strcmp(_char, "\b");
if (isBackSpace == -8) {
NSLog(@"Backspace was pressed");
}
return YES;
}
基本上,此方法会检测您按下的按钮(或刚刚按下的按钮)。此输入作为NSString输入。我们将此NSString转换为C char类型,然后将其与传统的退格符(\ b)进行比较。然后,如果此strcmp等于-8,我们可以将其检测为退格。
答案 8 :(得分:0)
swift 2:
if (string.characters.count == 0 && range.length == 1) {
return true
}
你应该像这样使用string.characters.count
答案 9 :(得分:0)
func keyboardInputShouldDelete(_ textField:UITextField)-> Bool { }
按下删除键时会调用此功能