如何在UITextField上模拟删除键?

时间:2010-06-09 16:42:18

标签: iphone ipad cocoa-touch uitextfield

我正在iPad上创建一个应用程序。我使用UITextField的{​​{1}}属性创建自定义键盘。要在光标位置插入文本,我使用副本&粘贴方法(http://dev.ragfield.com/2009/09/insert-text-at-current-cursor-location.html),效果很好。现在,我想创建删除键。我正在使用的代码是:

inputView

但是,正如您所知,它只会删除最后一个字符,无论光标位于何处。有谁知道更好的解决方案?

非常感谢!

10 个答案:

答案 0 :(得分:13)

只需致电[textField deleteBackward]即可。它会照顾光标位置并为您突出显示。

答案 1 :(得分:5)

我知道了! 这是我shouldChangeCharactersInRange方法的委托方法实现。


- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange) range replacementString:(NSString *) string {
    if ([string isEqualToString:@"⌫"]) {
        // NSLog(@"Backspace Pressed");
        NSMutableString *text = [textField.text mutableCopy];
        // NSLog(@"Length: %d Location: %d", range.length, range.location);
        if (range.length > 0) {
            [text deleteCharactersInRange:range];
        }
        if (range.length == 0 && range.location != 0) {
            NSRange backward = NSMakeRange(range.location - 1, 1);
            // NSLog(@"Length: %d Location: %d", backward.length, backward.location);
            [text deleteCharactersInRange:backward];
        }
        // NSLog(@"%@", text);
        textField.text = text;
        return NO;
    } else {return YES;}
}

它与UIPasteboard method密切配合,将文本转换为UITextField,这意味着您必须将删除键与将任意unicode字符粘贴到文本字段的方法相关联(例如),并且当调用委托方法时,您会发现替换字符串是该特定字符。

从那里,你可以从textField文本的可变字符串中删除range中的字符(如果有活动选择),或者如果没有选择则从范围中抓取前一个字符,只是一个插入符号

答案 2 :(得分:5)

晚会(再次; - )...对于iOS 5,UITextField符合UITextInput protocolUITextField扩展了selectedTextRange一些有用的方法和属性,包括{ {1}}属性,相当于selectedRange中的UITextView

答案 3 :(得分:3)

这是使用未记录的API的替代解决方案:selectionRange。我不知道这是否会通过Apple的评论,但如果该方法不可用并且也没有发出警告,那么它将不会使应用程序崩溃:)

这是UITextField:

上的类别
- (void)deleteBackward{
    @try{
        //check current selected range
        NSRange selectedRange = [[self valueForKey:@"selectionRange"] rangeValue];
        if (selectedRange.location == NSNotFound) selectedRange = NSMakeRange([[self text] length], 0);
        if (selectedRange.location < 1) return;

        //delete one char
        NSRange deleteRange = (selectedRange.length>0)?selectedRange:NSMakeRange(selectedRange.location-1,1);
        self.text = [self.text stringByReplacingCharactersInRange:deleteRange withString:@""];

        //adjust the selected range to reflect the changes
        selectedRange.location = deleteRange.location;
        selectedRange.range.length = 0;
        [self setValue:[NSValue valueWithRange:range] forKey:@"selectionRange"];
     }@catch (NSException *exception) {
          NSLog(@"failed but catched. %@", exception);
     }@finally {}
}


更新:2011/11/17

iOS5中的

UITextField和UITextView符合UITextInput协议(符合UIKeyInput),因此您可以[textField deleteBackward];执行与Del密钥完全相同的[textField insertText:@"text"];键盘,- (void) myDeleteBackward { if ([self conformsToProtocol:@protocol(UITextInput)]) { // iOS5 and later [textField deleteBackward]; // Or do below line if you are not deploy-targeting 5.0 or above and want to avoid warnings //[textField performSelector:@selector(deleteBackward)]; } else { // iOS4 and older versions // Do the trick :) @try{ ... }@catch (NSException *exception) { ... } } } ,它将插入文本并正确更新插入位置等。

因此,出于兼容性目的,可能您想要做的与此类似:

{{1}}

答案 4 :(得分:2)

考虑切换到UITextView,其具有selectedRange属性,用于获取当前选定的字符范围或光标位置(如果未选择任何内容)。不幸的是,UITextField没有这种方法,我还没有找到另一种方法来查找光标位置。

selectedRange属性的文档可以在here on Apple's website找到。它由NSRange组成,其中selectedRange.location是光标位置,selectedRange.length是所选字符的数量(如果没有选择任何字符,则为零。)您的代码必须看起来像这样:

textView.text = [textView.text stringByReplacingCharactersInRange:textView.selectedRange withString:@""];

答案 5 :(得分:0)

UITextView具有selectedRange属性。鉴于您可以使用以下代码构建一个范围:

textView.text = [textView.text stringByReplacingCharactersInRange:?? withString:@""];

UITextField没有此类范围属性。显然它有一个_selectionRange成员,但这是私有的。

我认为您的选择要么是切换到UITextView,要么阻止将光标放在文本末尾的任何位置并使用当前代码。

您可以随时向Apple提交错误报告,要求他们为UITextField记录selectedRange,或者要求特殊权限直接访问该字段。

答案 6 :(得分:0)

神圣的死灵,蝙蝠侠!对于iOS 3.2及更高版本,这是一个更简单的答案。在视图控制器的viewDidLoad或其他有权访问删除按钮的方法中执行此操作:

[self.myDeleteButton addTarget:nil action:@selector(deleteBackward) forControlEvents:UIControlEventTouchDown];

这与系统键盘的删除键的工作方式相同:它沿着响应者链发送deleteBackward消息。

答案 7 :(得分:0)

要删除光标后面的位置,可以使用textField.deleteBackward()

这是我在 Swift 5 中使用的,当我想在不删除 UITextField 中的文本的情况下获得结果

extension UITextField {
    /// simulates removing a character from 1 position behind the cursor and returns the result
    func backSpace() -> String {
        guard var text = text, // local text property, matching textField's text
              let selectedRange = selectedTextRange,
              !text.isEmpty
        else { return "" }
        
        let offset = offset(from: beginningOfDocument, to: selectedRange.start)
        
        let index = text.index(text.startIndex, offsetBy: offset-1)
        // this doesn't remove text from the textField, just the local text property
        text.remove(at: index)
        return text
    }
}

答案 8 :(得分:-1)

这个if (UITextField.text.length > 0) { [UITextField deleteBackward]; }怎么样:)

答案 9 :(得分:-1)

你可以试试这个:

if (txtTotal.text.length > 0) {
        txtTotal.text = [txtTotal.text substringToIndex:txtTotal.text.length-1];
    }