Как смоделировать клавишу удаления на UITextField? - PullRequest
6 голосов
/ 09 июня 2010

Я создаю приложение на iPad.Я создаю пользовательскую клавиатуру, используя свойство UITextField inputView.Чтобы вставить текст в позиции курсора, я использую метод copy & paste (http://dev.ragfield.com/2009/09/insert-text-at-current-cursor-location.html),, который работает нормально. Теперь я хочу создать ключ удаления. Я использую код:

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

Однако, как вы, возможно, знаете, он удаляет только последний символ, независимо от того, где находится курсор. Кто-нибудь знает лучшее решение?

Большое спасибо!

Ответы [ 9 ]

13 голосов
/ 12 сентября 2013

Просто позвоните [textField deleteBackward].Он позаботится о положении курсора и выделит вас.

5 голосов
/ 14 июня 2011

Я понял! Это моя реализация метода делегата для метода 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 для получения текста в UITextField, что означает, что вам нужно связать свой ключ удаления с методом, который вставляет произвольный символ Unicode в ваше текстовое поле (например, ), и когда вызывается метод делегата, вы узнаете, что замещающая строка - это конкретный символ.

Оттуда вы либо удаляете символы в range из изменяемой строки текста textField, если есть активное выделение, либо вы извлекаете предыдущий символ из диапазона, если выделение отсутствует, просто каретка.

5 голосов
/ 13 апреля 2012

Поздно до вечеринки (снова; -) ... В iOS 5 UITextField соответствует протоколу UITextInput , который расширяет UITextField некоторыми полезными методами и свойствами, включая selectedTextRange свойство, которое эквивалентно selectedRange в UITextView.

3 голосов
/ 26 июня 2011

Это альтернативное решение с использованием недокументированного 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) {
        ...
        }
    }
}
2 голосов
/ 09 июня 2010

Рассмотрите возможность переключения на UITextView, у которого есть свойство selectedRange для получения текущего выбранного диапазона символов или расположения курсора, если ничего не выбрано. К сожалению, UITextField не имеет этого метода, и я не нашел другого способа найти местоположение курсора.

Документацию по свойству selectedRange можно найти здесь здесь, на сайте Apple . Он состоит из NSRange, в котором selectedRange.location - это местоположение курсора, а selectedRange.length - это количество выбранных символов (или ноль, если ничего не выделено). Ваш код должен выглядеть примерно так:

textView.text = [textView.text stringByReplacingCharactersInRange:textView.selectedRange withString:@""];
0 голосов
/ 13 декабря 2012

Вы можете попробовать это:

if (txtTotal.text.length > 0) {
        txtTotal.text = [txtTotal.text substringToIndex:txtTotal.text.length-1];
    }
0 голосов
/ 31 марта 2012

Что насчёт этого if (UITextField.text.length > 0) { [UITextField deleteBackward]; }:)

0 голосов
/ 17 ноября 2011

Святой некро, Бэтмен! Вот гораздо более простой ответ для iOS 3.2 и более поздних версий. Сделайте это в вашем контроллере вида viewDidLoad или в другом методе, который имеет доступ к кнопке удаления:

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

Аналогично работает клавиша удаления системной клавиатуры: она отправляет сообщение deleteBackward по цепочке респондента.

0 голосов
/ 09 июня 2010

UITextView имеет свойство selectedRange. Учитывая, что вы можете построить диапазон для использования со следующим кодом:

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

UITextField не имеет такого свойства диапазона. Очевидно, у него есть _selectionRange член, но это личное.

Я думаю, что вы можете либо переключиться на UITextView, либо не использовать курсор в любом месте, кроме конца текста и использовать ваш текущий код.

Вы всегда можете отправить отчет об ошибке в Apple, запрашивая у них документ selectedRange для UITextField, или запросить специальное разрешение для прямого доступа к полю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...