【问题标题】:iPhone Force Textbox Input to Upper CaseiPhone强制文本框输入为大写
【发布时间】:2011-01-02 21:15:44
【问题描述】:

如何强制输入到 iPhone 上的文本框中的字符为大写?

【问题讨论】:

    标签: iphone cocoa-touch uitextfield uppercase


    【解决方案1】:

    我对上述一些答案的一个问题是,如果您尝试设置textfield.text,您将失去光标位置。因此,如果用户试图编辑文本的中间部分,光标会跳到末尾

    这是我简单的 Swift 解决方案,仍然使用UITextFieldDelegate

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    
        if textField == textFieldToUppercase {
            if string == "" {
                // User presses backspace
                textField.deleteBackward()
            } else {
                // User presses a key or pastes
                textField.insertText(string.uppercaseString)
            }
            // Do not let specified text range to be changed
            return false
        }
    
        return true
    }
    

    如果用户按下键盘上的 ReturnDone 等键,您仍然需要处理。只需添加:

    if string == "\n" {
        // Do something when 'Done' is pressed, like dismiss the keyboard
        textField.resignFirstResponder()
        return false
    }
    

    ...func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool 的内部。

    【讨论】:

      【解决方案2】:

      在文本字段中自动输入大写:

      案例1:添加UITextDelegate协议并实现如下方法

      -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
      {
          textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string capitalizedString]];
      
          return NO;
      }
      

      案例 2:在视图控制器的 ViewDidLoad() 方法中设置以下参数。虽然在这种情况下,用户可以关闭键盘上的大写按钮。

      urTextFieldName.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
      

      【讨论】:

        【解决方案3】:

        这是我的代码,当我有 6 个文本字段时

        希望你能明白

        - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
            if (textField==self.textField6) {
                self.textField6.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]];
                return NO;
            }
            return YES;
        }
        

        【讨论】:

          【解决方案4】:

          我从以前的答案中得到了启发(谢谢),但他们都对我有一些缺陷:

          • 当您还需要小写甚至更多控制时,使用 textField.autocapitalizationType 无济于事。
          • textField.text = "my String" 将光标设置到 textField 的末尾,这在编辑时真的很烦人。

          所以这是我的 Swift 代码,它可以让您完全控制输入的字符(大写、小写、忽略...),并让光标位于您期望的位置。该代码经过测试可以与多个文本字段一起使用。

          编辑:使用 iOS 8.3 测试

              func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
          
              // modify string as and if the user wants:
              // at this place you can also return false to ignore the replacement completely.
              var str = string
              if !Defaults.isUpperOrLower() {
                  if Defaults.isAllLetterUpper() {
                      str = string.uppercaseString
                  } else {
                      str = string.lowercaseString
                  }
              }
          
              // updating textField.text sets the curser position to the end
              // so we store the cursor position before updating.
              let selRange = textField.selectedTextRange
          
              // Update textField as requested and modified.
              var txt = textField.text as NSString
              textField.text = txt.stringByReplacingCharactersInRange(range, withString: str)
          
              // recalculate and set the cursor position in the textField:
              // tested with
              // 1. typing a character
              // 2. backspace
              // 3. selecting a range + backspace
              // 4. selecting a range + typing a character
              if let selRange = selRange {
                  var newPosition: UITextPosition?
                  if range.length == 0 {
                      // normal character
                      newPosition = textField.positionFromPosition(selRange.end, inDirection: UITextLayoutDirection.Right, offset: count(string))
                  } else {
                      // backspace
                      newPosition = textField.positionFromPosition(selRange.end, inDirection: UITextLayoutDirection.Left, offset: range.length - count(string))
                  }
                  textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: newPosition)
              }
          
              // return false because we did everything manually
              return false
          }
          

          【讨论】:

            【解决方案5】:

            也许我还没有找到这种方法的所有缺陷,但到目前为止它对我来说效果很好。如果您沿着从 -textField:shouldChangeCharactersInRange:replacementString: 返回 NO 的路线走,似乎可以避免将选择跳转到最后的问题。由于 UITextField 符合 UIKeyInput,只需重写方法 -insertText: 将输入字符串更改为大写,然后再使用大写字符串调用 super:

            - (void)insertText:(NSString *)text {
                NSString *uppercaseText = [text uppercaseString]
                [super insertText:uppercaseText]
            }
            

            或者,如果您已经迁移到 Swift:

            override func insertText(text: String) {
                let uppercaseText = text.uppercaseString
                super.insertText(uppercaseText)
            }
            

            【讨论】:

              【解决方案6】:

              return NO 会有返回按钮的问题;

              最好用这个

              - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
                  if ([[string uppercaseString] isEqualToString:string]) {
                      return YES;
                  }
              
                  NSString *newString = [[textField.text stringByAppendingString:string] uppercaseString];
                  textField.text = newString;
                  return NO;
              
              }
              

              【讨论】:

                【解决方案7】:

                最简单的方法是,实现文本字段的编辑更改方法并将文本字段的文本值设置为输入文本的大写表示

                - (IBAction)TextFieldEditingChanged:(id)sender
                {
                    _yourTextField.text = [_yourTextField.text uppercaseString];
                }
                

                【讨论】:

                  【解决方案8】:

                  虽然所有其他答案确实有效(它们使输入大写),但它们都存在未保留光标位置的问题(尝试在现有文本的中间插入一个字符)。这显然发生在UITextFieldtext 属性的设置器中,我还没有找到以编程方式恢复它的方法(例如,恢复原来的selectedTextRange 不起作用)。

                  不过,好消息是,有一种直接的方法可以替换UITextField(或UITextView)文本的一部分,而不会出现此问题:

                  - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
                  {
                      // not so easy to get an UITextRange from an NSRange...
                      // thanks to Nicolas Bachschmidt (see http://stackoverflow.com/questions/9126709/create-uitextrange-from-nsrange)
                      UITextPosition *beginning = textField.beginningOfDocument;
                      UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
                      UITextPosition *end = [textField positionFromPosition:start offset:range.length];
                      UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end];
                  
                      // replace the text in the range with the upper case version of the replacement string
                      [textField replaceRange:textRange withText:[string uppercaseString]];
                  
                      // don't change the characters automatically
                      return NO;
                  }
                  

                  有关这些方法的更多信息,请参阅UITextInput 的文档。

                  【讨论】:

                  • 这很好用,但缺点是返回键状态不会随着字段内容的变化而更新(可能是因为返回值为 NO。)
                  【解决方案9】:

                  与其测试字符是大写还是小写,不如假设它是小写。简单得多。

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

                  方法:

                  NSString *newString = [[textField.text stringByAppendingString:string] uppercaseString];
                  textField.text = newString;
                  
                  return NO;
                  

                  【讨论】:

                    【解决方案10】:

                    这个解决方案并不完全令人满意。

                    即使将autocapitalizationType 设置为UITextAutocapitalizationTypeAllCharacters,用户仍然可以按下大写字母来释放大写锁定。而textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; return NO; 的解决方案并不是那么好:如果用户编辑文本的中间,我们会丢失编辑点(在textField.text = 之后,编辑光标会移动到字符串的末尾)。

                    我已经混合使用了这两种解决方案,以下是我的建议:设置UITextAutocapitalizationTypeAllCharacters,并将以下代码添加到UITextField 的委托中。

                    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
                    replacementString:(NSString *)string {
                    
                        // Check if the added string contains lowercase characters.
                        // If so, those characters are replaced by uppercase characters.
                        // But this has the effect of losing the editing point
                        // (only when trying to edit with lowercase characters),
                        // because the text of the UITextField is modified.
                        // That is why we only replace the text when this is really needed.
                        NSRange lowercaseCharRange;
                        lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];
                    
                        if (lowercaseCharRange.location != NSNotFound) {
                    
                            textField.text = [textField.text stringByReplacingCharactersInRange:range
                                                                                     withString:[string uppercaseString]];
                            return NO;
                        }
                    
                        return YES;
                    }
                    

                    【讨论】:

                    • 谢谢,这正是我要找的。​​span>
                    • 如您所见,设置text 属性始终将插入符号置于文本末尾。我做了一些实验,实际上已经找到了一种在不丢失插入符号位置的情况下做到这一点的方法。请参阅下面的答案。
                    • 此解决方案与此处建议的所有其他解决方案一样,会影响基于滑动的自定义键盘的行为......仍在尝试找到更好的东西。
                    • 找到比这更好的解决方案了吗?
                    【解决方案11】:

                    UITextField 上将autocapitalizationType 设置为UITextAutocapitalizationTypeAllCharacters

                    更多详情请见UITextInputTraits protocol (adopted by UITextField)

                    【讨论】:

                    • 你的帮助很好。但它并不完整。请看这里得到我真正的问题:farm5.static.flickr.com/4072/4263944357_6db39314bc.jpg
                    • 嗯,这是设备的行为,是的。如果您希望字母立即显示为大写,您可以从UITextFieldDelegate 实现textField:shouldChangeCharactersInRange:replacementString:,当输入小写字母时,将其更改为对应的大写。
                    • 这是我的代码,它不起作用。输入的文本仍然小写 :( - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { string = [string uppercaseString]; return TRUE; }
                    • 当然不是,string 只是作为参数传递。你必须做类似textField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; return NO;
                    猜你喜欢
                    • 1970-01-01
                    • 2010-09-17
                    • 2018-10-01
                    • 2013-04-29
                    • 2018-03-11
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多