问题
I have a question about iOS UIKeyboard
.
I have a UITextField
and I would to have the keyboard
with only uppercase characters.
I use a storyboard
and I tried to set the Cpitalization
as "All characters
" to UITextField properties
.
But this not solve my problem...any suggestion?
回答1:
Set your textfield type autocapitalizationType
to UITextAutocapitalizationTypeAllCharacters
on the UITextField
self.yourTexField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
After call delegate
// delegate method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSRange lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];
if (lowercaseCharRange.location != NSNotFound) {
textField.text = [textField.text stringByReplacingCharactersInRange:range
withString:[string uppercaseString]];
return NO;
}
return YES;
}
回答2:
For those looking for a Swift version.
Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
textField.text = (textField.text! as NSString).replacingCharacters(in: range, with: string.uppercased())
return false
}
Original answer
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
textField.text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string.uppercaseString)
return false
}
Using the Capitalization: All Characters
property just forces keyboard to open with caps lock on, but lets the user to turned it off.
回答3:
One issue I have with some of the above answers is if you try and set textfield.text
, you will lose the cursor position. So if a user tries to edit the middle of the text, the cursor will jump to the end.
Here is my Swift solution, still using 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
}
回答4:
The syntax is now
Swift 2
textField.autocapitalizationType = UITextAutocapitalizationType.AllCharacters
Swift 3
textField.autocapitalizationType = .allCharacters
回答5:
This is a different approach I used, where it does the following:
- Enforces capitalization as soon as the character is entered
- Catches situations where the user disables caps lock even if it textfield is set to auto caps
- Allows for easy editing
- Works with Swift 2.2
First, register a notification to be updated whenever any changes occur in the textfield.
textField.addTarget(self, action: #selector(YourClassName.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)
Then, implement textFieldDidChange
.
func textFieldDidChange(textField: UITextField) {
textField.text = textField.text?.uppercaseString
}
I chose this to avoid a situation where the user sees an uneven experience of some capitalized, but then changed once they move to the next character.
回答6:
Set UITextField
property autocapitalizationType
to UITextAutocapitalizationTypeAllCharacters
. This will make all characters to appear in upper case. Also visit here to find more about textfields
回答7:
Swift 4.0 Version:
First set the delegate for the textfield you want to uppercase to the current ViewController (click drag from the textfield to the currentViewController to set the delegate).
After add the extension:
extension CurrentViewController: UITextFieldDelegate{
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//refference to the textfield you want to target
if textField.tag == 5{
textField.text = (textField.text! as NSString).replacingCharacters(in: range, with: string.uppercased())
return false
}
return true
}
}
回答8:
You should avoid to use delegate method
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
because this will trigger an unwanted behaviour with iOS 13 + QuickPath typing (the iOS' Swiftkey Keyboard counterpart).
If you swipe on the keyboard and write "hello", it will write "HELLOHELLOHELLOHELLOHELLO" into the textfield. This is because the method is called multiple times and it appends the just changed text via textField.text = uppercasedValue
.
The right way is to observe the .editingChange
event and uppercase then the value. For example:
func awakeFromNib() {
textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
}
and
@objc func textFieldDidChange() {
textField.text = textField.text?.uppercased()
}
回答9:
You can also use this code.
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
// Uppercase for string which you need
textField.text = [textField.text stringByReplacingCharactersInRange:range
withString:[string uppercaseString]];
// return NO because You have already done it in above code
return NO;
}
回答10:
The simplest way would be to implement the editing changed method of the text field and set the textfield's text value to upper case representation of the entered text.
@property (nonatomic, strong) IBOutlet UITextField *yourTextfield
// add target in code or use interface builder
[self.yourTextField addTarget:self
action:@selector(uppercaseTextField)
forControlEvents:UIControlEventEditingChanged];
- (IBAction)uppercaseTextField:(UITextField*)textField
{
textField.text = [textField.text uppercaseString];
}
回答11:
Finally I found the way that respects also editing text in the middle of the string in UITextField
.
The problem is that if you replace whole text by UITextFiled.text
property the actual cursor moves to end of text. So you need to use .replace()
method to specify exactly which characters you want to update to upperCase.
Last thing is to return string.isEmpty
as return value of function - otherwise you are not allowing deleting of text.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text, let textRange = Range(range, in: text) {
let uppercasedString = string.uppercased()
let updatedText = text.replacingCharacters(in: textRange, with: uppercasedString)
if let selectedTextRange = textField.selectedTextRange {
textField.replace(selectedTextRange, withText: uppercasedString)
approveButtonState(vin: updatedText)
}
return string.isEmpty
}
return false
}
回答12:
Just one line code in ViewDidLoad/ViewDidAppear:
If you simply want to see the characters typed regardless of the UPPER/lower case to all CAPITALS/UPPER CASE paste below code either in ViewDidLoad/ViewDidAppear
self.MyTextField.autocapitalizationType = .allCharacters
above line changes all letters into CAPITALS while you type automatically
回答13:
Maybe it's a bit late for an answer here, but as I have a working solution someone might find it useful.
Well, in the following textfield delegate method, check if the new string contains any lowercase characters. If so, then:
- Append the character that was just typed to the textfield's text.
- Make all the textfield's text uppercased.
- Make sure that
false
is returned by the method.
Otherwise just return true
and let the method work as expected.
Here's its implementation:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
var returnValue = true
let lowercaseRange = string.rangeOfCharacter(from: CharacterSet.lowercaseLetters)
if let _ = lowercaseRange?.isEmpty {
returnValue = false
}
if !returnValue {
textField.text = (textField.text! + string).uppercased()
}
return returnValue
}
The above has worked perfectly for me, and a similar implementation works for textviews too, after making the proper adjustments first of course.
Hope it helps!
回答14:
/**
We take full control of the text entered so that lowercase cannot be inserted
we replace lowercase to uppercase
*/
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// No spaces allowed
if string == " " {
return false
}
// delete key pressed
if string == "" {
textField.deleteBackward()
return false
}
// We only allow alphabet and numbers
let numbersAndLettersSet = CharacterSet.alphanumerics
if string.lowercased().rangeOfCharacter(from: numbersAndLettersSet) == nil {
return false
}
// Add the entered text
textField.insertText(string.uppercased())
// Return false as we are doing full control
return false
}
回答15:
Here there's my situation and how I achieved to force the upper text:
- custom class (
UITextField
subclass) - don't want to use delegate
UITextFieldDelegate
methods
Solution proposed from @CodeBender was pretty much what I was looking for but the cursor always jump to the end as noticed from @Dan.
class MyCustomTextField: UITextField {
...
addTarget(self, action: #selector(upperText), for: .editingChanged)
...
...
@objc private func upperText() {
let textRange = selectedTextRange
text = text?.uppercased()
selectedTextRange = textRange
}
This will set the cursor always in the correct position (where it was) even if user adds text in "the middle".
回答16:
Using the following text field delegate method it can be done:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
//--- Making uppercase ---//
if (textField == yourTextField ) {
NSRange lowercaseCharRange;
lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];
if (lowercaseCharRange.location != NSNotFound) {
textField.text = [textField.text stringByReplacingCharactersInRange:range
withString:[string uppercaseString]];
return NO;
}
}
}
Hope this helps.
来源:https://stackoverflow.com/questions/21092182/uppercase-characters-in-uitextfield