Как обнаружить ключ удаления на UITextField в iOS 8?
Я подклассифицировал UITextField и реализовал метод deleteBackward для метода UIKeyInput для обнаружения обратного пространства. Это отлично работает на iOS 7, но не на iOS 8.
deleteBackward больше не вызывается на UITextField, когда я нажимаю клавишу backspace.
Я проверил документацию и примечания к выпуску, и ничто не указывает на причину, почему это может произойти. Любые указатели?
Ответы
Ответ 1
Вы должны посмотреть пример MBContactPicker в github. Удаление контактов в MBContactPicker с помощью кнопки Backspace на iOS8, проверенной мной. И это работает очень! Вы можете использовать его как пример.
Автор MBContactPicker использует следующий метод: когда UITextField должен быть пустым (или до вызова getFirstResponder, когда он пуст), он сохраняет один символ пробела. И затем, когда вы нажимаете кнопку Backspace (когда фокус установлен на конец текста вашего UITextField), метод
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)text
будет работать. В нем вы должны использовать проверку следующим образом:
NSString *resultString = [textField.text stringByReplacingCharactersInRange:range withString:text];
BOOL isPressedBackspaceAfterSingleSpaceSymbol = [text isEqualToString:@""] && [resultString isEqualToString:@""] && range.location == 0 && range.length == 1;
if (isPressedBackspaceAfterSingleSpaceSymbol) {
// your actions for deleteBackward actions
}
Итак, вы всегда должны контролировать, что UITextField содержит одиночные пробелы.
Это не взломать. Таким образом, пользователь не заметил, что какое-то поведение было изменено.
Ответ 2
Многие люди говорили, что это ошибка, но поскольку эта проблема все еще существует в 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, однако у вас не должно возникнуть проблемы с его использованием. Мое приложение с этим кодом находится в магазине приложений.
Чтобы объяснить немного, вызывают супер реализацию этого метода, чтобы избежать потери кода. После вызова -deleteBackward
, если текст отсутствует, а версия iOS находится между 8-8.2.
РЕДАКТИРОВАТЬ: 1/22/15
Также может оказаться полезным подкласс метода -deleteBackward
вашего подкласса UITextField
. Это исправляет несколько условных ошибок. Один из них, если вы используете пользовательскую клавиатуру. Вот пример метода.
- (void)deleteBackward {
BOOL shouldDismiss = [self.text length] == 0;
[super deleteBackward];
if (shouldDismiss) {
if ([self.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
[self.delegate textField:self shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
}
}
}
РЕДАКТИРОВАТЬ: 4/13/15
Как комментировал @Gee.E, iOS 8.3 исправил эту проблему. Код был обновлен, чтобы отразить изменения.
Ответ 3
Вы можете обнаружить, когда пользователь удаляет текст, используя обратное пространство, реализуя метод делегирования UITextField:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (range.length==1 && string.length==0)
NSLog(@"backspace tapped");
return YES;
}
Ответ 4
Swift 2.2:
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "" {
print("Backspace has been pressed")
}
return true
}
Ответ 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;
}
Ответ 6
версия Swift 2.0 для обнаружения удаления BackSpace, ссылка на кодовое сообщение от 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
}
Ответ 7
- (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, мы можем обнаружить его как backspace.
Ответ 8
swift 2:
if (string.characters.count == 0 && range.length == 1) {
return true
}
вы должны использовать это как string.characters.count