iPhone: отключить «двойное нажатие пробел для». ярлык? - PullRequest
10 голосов
/ 05 апреля 2010

По умолчанию, если дважды нажать пробел на iPhone или iPad, вместо «» (два пробела) вы получите «.» (Точка, за которой следует пробел). Есть ли способ отключить этот ярлык в коде?

Обновление: отключение автокоррекции через UITextInputTraits не работает.

Обновление 2: Понял! Смотрите мой пост ниже.

Ответы [ 8 ]

12 голосов
/ 24 мая 2011

У меня есть ответ, основанный на ответе, приведенном Шезе выше.

Метод Чейза не позволяет вам вводить два пробела в последовательности - это нежелательно в некоторых ситуациях. Вот способ полностью отключить автоматическую вставку:

Swift

В методе делегата:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    //Ensure we're not at the start of the text field and we are inserting text
    if range.location > 0 && text.count > 0
    {
        let whitespace = CharacterSet.whitespaces

        let start = text.unicodeScalars.startIndex
        let location = textView.text.unicodeScalars.index(textView.text.unicodeScalars.startIndex, offsetBy: range.location - 1)            

        //Check if a space follows a space
        if whitespace.contains(text.unicodeScalars[start]) && whitespace.contains(textView.text.unicodeScalars[location])
        {
            //Manually replace the space with your own space, programmatically
            textView.text = (textView.text as NSString).replacingCharacters(in: range, with: " ")

            //Make sure you update the text caret to reflect the programmatic change to the text view
            textView.selectedRange = NSMakeRange(range.location + 1, 0)

            //Tell UIKit not to insert its space, because you've just inserted your own
            return false
        }
    }

    return true
}

Теперь вы можете нажимать пробел столько раз, сколько хотите, вставляя только пробелы.

Objective-C

В методе делегата:

- (BOOL) textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text

Добавьте следующий код:

//Check if a space follows a space
if ( (range.location > 0 && [text length] > 0 &&
      [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[text characterAtIndex:0]] &&
      [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[[textView text] characterAtIndex:range.location - 1]]) )
{
    //Manually replace the space with your own space, programmatically
    textView.text = [textView.text stringByReplacingCharactersInRange:range withString:@" "];

    //Make sure you update the text caret to reflect the programmatic change to the text view
    textView.selectedRange = NSMakeRange(range.location+1, 0);  

    //Tell Cocoa not to insert its space, because you've just inserted your own
    return NO;
}
4 голосов
/ 11 июня 2010

Поместите это в ваш класс делегата:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

 //Check for double space
 return !(range.location > 0 && 
          [string length] > 0 &&
          [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[string characterAtIndex:0]] &&
          [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[[textField text] characterAtIndex:range.location - 1]]);

}
1 голос
/ 08 апреля 2019

Это самое простое решение, которое я смог получить для решения этой проблемы в Swift 4. Он более полный, чем некоторые другие ответы, так как позволяет вводить несколько пробелов в строке.

func disableAutoPeriodOnDoubleTapSpace() {
    textField.addTarget(self, action: #selector(replaceAutoPeriod), for: .editingChanged)
}

@objc private func replaceAutoPeriod() {
    textField.text = textField.text.replacingOccurrences(of: ". ", with: "  ")
}

Если ваше текстовое поле отформатировано с .attributedText, вам нужно будет сохранить старый .selectedTextRange до и сбросить его после установки значения .text. В противном случае ваш курсор переместится в конец текста при редактировании в середине строки.

Надеюсь, это поможет кому-то, кто попробовал все остальные ответы без удачи!

1 голос
/ 19 декабря 2018

Это реализация в Swift 4.0 для текстовых полей, копирующая ответ Симеона:

func textField(_ textField: UITextField, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    //Ensure we're not at the start of the text field and we are inserting text
    if range.location > 0 && text.count > 0{
        let whitespace = CharacterSet.whitespaces
        //get list of whitespace characters

        let start = text.unicodeScalars.startIndex
        if let textFieldText = textField.text{
            let location = textFieldText.unicodeScalars.index(textFieldText.unicodeScalars.startIndex, offsetBy: range.location - 1)

            //Check if a space follows a space
            if whitespace.contains(text.unicodeScalars[start]) && whitespace.contains(textFieldText.unicodeScalars[location]){

                //Manually replace the space with your own space, programmatically
                textField.text = (textFieldText as NSString?)?.replacingCharacters(in: range, with: " ")

                if let pos = textField.position(from: textField.beginningOfDocument, offset: range.location + 1)
                {
                    //Make sure you update the text caret to reflect the programmatic change to the text view
                    textField.selectedTextRange = textField.textRange(from: pos, to: pos)


                    //Tell UIKit not to insert its space, because you've just inserted your own
                    return false
                }
            }
        }
    }
    return true
}

Надеюсь, это поможет!

РЕДАКТИРОВАТЬ: добавлен отсутствующий оператор возврата в нижней части.

1 голос
/ 30 октября 2014

Более простое решение, которое я нашел для работы UITextView, выглядит следующим образом:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if ([text isEqualToString:@". "] && range.length == 1) {
        NSMutableAttributedString *attributedString = [textView.attributedText mutableCopy];
        [attributedString replaceCharactersInRange:range withString:@" "];
        textView.attributedText = attributedString;
        textView.selectedRange = NSMakeRange(range.location + 1, 0);

        return NO;
    }
    return YES;
}

Это позволяет многократно вводить несколько пробелов, а также обрабатывать приписанный текст. Единственный случай, с которым я столкнулся с ошибкой, это вставка точки и пробела с одним выбранным символом.

1 голос
/ 25 апреля 2012

Еще одна версия одного из опубликованных симеонов (это была версия Chaise's).Этот работает с текстовыми полями (UITextField).Вам придется настроить UITextFieldDelegate для этого, чтобы сделать что-нибудь.Я закомментировал строку для обновления каретки, но она все еще работает.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)text
{
    //Check if a space follows a space
    if ( (range.location > 0 && [text length] > 0 &&
          [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[text characterAtIndex:0]] &&
          [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[[textField text] characterAtIndex:range.location - 1]]) )
    {
        //Manually replace the space with your own space, programmatically
        textField.text = [textField.text stringByReplacingCharactersInRange:range withString:@" "];

        //Make sure you update the text caret to reflect the programmatic change to the text view
//      textField.selectedTextRange = NSMakeRange(range.location+1, 0);  

        //Tell Cocoa not to insert its space, because you've just inserted your own
        return NO;
    }
    return YES;
}
0 голосов
/ 07 апреля 2010

ОК, я понял это. Добавьте в свой делегат UITextView следующее:

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if([text isEqualToString:@". "])
        return NO;
}
0 голосов
/ 05 апреля 2010

Не думаю, что есть способ отключить это, но посмотрите UITextInputTraits . Это позволяет вам объявить свойства вашего поля, например, вы можете сказать, если это для ввода URL. Это влияет на поведение клавиатуры. Если причина, по которой вы не хотите использовать двойной пробел для получения точки и пробела, заключается в том, что текст должен быть буквально тем, что пользователь ввел по какой-то причине, возможно, вы хотите отключить автокоррекцию. Возможно, отключение автокоррекции отключит двойной пробел на период, я не знаю.

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