【问题标题】:iPhone: Disable the "double-tap spacebar for ." shortcut?iPhone:禁用“双击空格键”。捷径?
【发布时间】:2011-02-04 07:34:29
【问题描述】:

默认情况下,如果您在 iPhone 或 iPad 上点按两次空格键,您会得到“. ”(句点后跟一个空格),而不是“  ”(两个空格)。有什么办法可以在代码中禁用这个快捷方式?

更新:通过 UITextInputTraits 禁用自动更正不起作用。

更新 2:知道了!请参阅下面的帖子。

【问题讨论】:

  • 这不是应用程序的问题。 用户可以根据需要通过设置实用程序将其关闭。
  • 我正在编写一个应用程序,用户将在其中连续输入许多空格进行缩进。
  • 致问“为什么?”的 Matchu 和 Andrew Medico……我发现了一个用例:在 UISearchBar 中,您知道用户正在输入一系列要用作条件的单词。不需要一段时间。更糟糕的是,句号会扭曲搜索结果。
  • 在我的音乐应用程序中,用户输入多个空格以将和弦符号与歌词对齐,并且不需要自动句点。但是,大多数用户仍然希望在其他应用程序中启用该功能,甚至在此应用程序的其他字段中启用该功能,因此为特定字段关闭它有一定的好处。

标签: iphone cocoa-touch


【解决方案1】:

根据上面 Chaise 给出的答案,我有一个答案。

Chaise 的方法不允许您按顺序键入两个空格 - 这在某些情况下是不可取的。这是一种完全关闭自动句号插入的方法:

斯威夫特

在委托方法中:

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
}

现在您可以随心所欲地轻按空格键,只插入空格。

目标-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;
}

【讨论】:

  • 它对我有用,可以避免双倍空格,感谢 Simeon 先生 :)
  • 这不再适用于属性文本。 textView.text = ... 行现在应该是:NSMutableAttributedString *attributedString = [textView.attributedText mutableCopy]; [attributedString replaceCharactersInRange:range withString:@" "]; textView.attributedText = attributedString;
  • @RohitKP Swift 版本添加
  • 很难适应 Swift 4 并在 textField 而不是 textView 中使用。与上面讨论的相同用例 - 一个搜索字段,其中查找连续空格的可能性远大于在句子末尾想要一个句点。在 textField 中使用它需要进行哪些更改?
  • 输入表情符号后跟双空格时Swift代码崩溃)
【解决方案2】:

这是我可以在 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 值后将其重置。否则,在字符串中间进行编辑时,您的光标将移动到文本的末尾。

希望这对尝试所有其他答案但没有运气的人有所帮助!

【讨论】:

    【解决方案3】:

    把它放在你的委托类中:

    - (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]]);
    
    }
    

    【讨论】:

    • 在编辑并尝试在两个单词之间插入时,会出现此解决方案的一个问题。第一个字符可能是空格并被过滤。下面 simeon 的回答可以解决这个问题,或者使用 stackoverflow.com/questions/1528049/… 的变体,用两个空格替换“.”。
    • shouldChangeCharactersInRange: 的坏消息是它不区分文本插入和删除。如果你删除最后一个字符,NSRange 看起来就像你复制剩余的文本一样。如果你认为没问题,试着选择并删除单词中间的一些字符:在这种情况下我什至不知道如何解释 NSRange。可能是bug,也可能是模拟器的bug……
    • 是否有理由使用[NSCharacterSet whitespaceCharacterSet] 而不仅仅是检查@" " 空格字符?由于此字符集包含空格和制表符。
    【解决方案4】:

    这是 Swift 4.0 中文本字段的实现,复制 Simeon 的答案:

    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
    }
    

    希望这会有所帮助!

    编辑:在底部添加了一个缺少的返回语句。

    【讨论】:

    • 您忘记在最后添加 return true。原样的代码不会编译。
    【解决方案5】:

    simeon 发布的另一个版本(这是 Chaise 的版本)。这个适用于文本字段 (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;
    }
    

    【讨论】:

      【解决方案6】:

      我发现适用于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;
      }
      

      这允许重复输入多个空格并处理属性文本。我发现它失败的唯一情况是粘贴句点和空格,并且已经选择了一个字符。

      【讨论】:

        【解决方案7】:

        斯威夫特 5

        我在仔细管理的 textField 输入上下文中尝试允许“”和“-”但不允许“。”时发现了这个问答树。也不是由双空格或双 - 引起的“-”。

        所以,我对委托函数进行了如下简化和修改:

            func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                if textField.text?.last == " " && string == " " {
                    textField.text = (textField.text as NSString?)?.replacingCharacters(in: range, with: " ")
                    if let pos = textField.position(from: textField.beginningOfDocument, offset: range.location + 1) {
                    // updates the text caret to reflect the programmatic change to the textField
                        textField.selectedTextRange = textField.textRange(from: pos, to: pos)
                        return false
                    }
                }
                if textField.text?.last == "-" && string == "-" {
                    textField.text = (textField.text as NSString?)?.replacingCharacters(in: range, with: "-")
                    if let pos = textField.position(from: textField.beginningOfDocument, offset: range.location + 1) {
                    // updates the text caret to reflect the programmatic change to the textField
                        textField.selectedTextRange = textField.textRange(from: pos, to: pos)
                        return false
                    }
                }
                return true
            }
        

        【讨论】:

          【解决方案8】:

          我认为没有办法完全关闭此功能,但请查看 UITextInputTraits。这使您可以声明字段的属性,例如,您可以说它是否用于输入 URL。这会影响键盘的行为。如果您不希望双空格产生句点和空格的原因是文本应该是用户出于某种原因输入的字面内容,那么您可能想要关闭自动更正。有可能关闭自动更正会关闭句号的双倍空格,我不知道。

          【讨论】:

          • 应该是评论而不是答案。关闭自动更正并不会在一段时间内关闭双倍空格,仅供参考。
          【解决方案9】:

          好的,我想通了。在您的 UITextView 委托中,添加以下内容:

          -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
              if([text isEqualToString:@". "])
                  return NO;
          }
          

          【讨论】:

          • 在使用 UITextField 时似乎不起作用 :( textField:shouldChangeCharactersInRange:replacementString: 不会因为此更改而被触发...
          • 不是一个有用的解决方案。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-23
          • 1970-01-01
          • 1970-01-01
          • 2011-06-24
          • 2019-05-28
          相关资源
          最近更新 更多