IPad nie ma klawiatury numerycznej, tak jak ma to miejsce w przypadku iPhone'a / iPoda.
Szukam sposobu, aby ograniczyć klawiaturę użytkownika do akceptowania tylko wartości od 0 do 9.
Wyobrażałbym sobie użycie „shouldChangeCharactersInRange” UITextField, ale nie znam najlepszego sposobu na jego implementację.
ios
ipad
cocoa-touch
uitextfield
uikeyboard
Demasterpl
źródło
źródło
Odpowiedzi:
W ten sposób możesz poradzić sobie z problemem w polu weryfikacji numeru SSN, możesz zmodyfikować maksymalną długość i usunąć
if
instrukcję sprawdzania typu klawiatury, jeśli zajdzie taka potrzeba.Istnieje również logika, która blokuje alerty o maksymalnej długości, gdy użytkownik pisze, w przeciwieństwie do wklejania danych.
W kontekście tego kodu
presentAlert()/presentAlert:
jest tylko kilka podstawowych funkcji, które przedstawiają plikUIAlertController
(lub starszyUIAlertView
) przy użyciu przekazanego ciągu komunikatu.Szybki 5
// NOTE: This code assumes you have set the UITextField(s)'s delegate property to the // object that will contain this code, because otherwise it would never be called. // // There are also some better stylistic approaches in Swift to avoid all the // nested statements, but I wanted to keep the styles similar to allow others // to contrast and compare between the two languages a little easier. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // Handle backspace/delete guard !string.isEmpty else { // Backspace detected, allow text change, no need to process the text any further return true } // Input Validation // Prevent invalid character input, if keyboard is numberpad if textField.keyboardType == .numberPad { // Check for invalid input characters if CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) { // Present alert so the user knows what went wrong presentAlert("This field accepts only numeric entries.") // Invalid characters detected, disallow text change return false } } // Length Processing // Need to convert the NSRange to a Swift-appropriate type if let text = textField.text, let range = Range(range, in: text) { let proposedText = text.replacingCharacters(in: range, with: string) // Check proposed text length does not exceed max character count guard proposedText.count <= maxCharacters else { // Present alert if pasting text // easy: pasted data has a length greater than 1; who copy/pastes one character? if string.count > 1 { // Pasting text, present alert so the user knows what went wrong presentAlert("Paste failed: Maximum character count exceeded.") } // Character count exceeded, disallow text change return false } // Only enable the OK/submit button if they have entered all numbers for the last four // of their SSN (prevents early submissions/trips to authentication server, etc) answerButton.isEnabled = (proposedText.count == 4) } // Allow text change return true }
Cel C
// NOTE: This code assumes you have set the UITextField(s)'s delegate property to the // object that will contain this code, because otherwise it would never be called. - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // Handle backspace/delete if (!string.length) { // Backspace detected, allow text change, no need to process the text any further return YES; } // Input Validation // Prevent invalid character input, if keyboard is numberpad if (textField.keyboardType == UIKeyboardTypeNumberPad) { if ([string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet].invertedSet].location != NSNotFound) { [self presentAlert: @"This field accepts only numeric entries."]; return NO; } } // Length Validation NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string]; // Check proposed text length does not exceed max character count if (proposedText.length > maxCharacters) { // Present alert if pasting text // easy: pasted data has a length greater than 1; who copy/pastes one character? if (string.length > 1) { // Pasting text, present alert so the user knows what went wrong [self presentAlert: @"Paste failed: Maximum character count exceeded."]; } // Character count exceeded, disallow text change return NO; } // Only enable the OK/submit button if they have entered all numbers for the last four // of their SSN (prevents early submissions/trips to authentication server, etc) self.answerButton.enabled = (proposedText.length == maxCharacters); // Allow text change return YES; }
źródło
Możesz użyć tego kodu, aby zezwolić tylko na liczbę w textField.
Wcześniej ustaw delegata dla textField
textFieldName.delegate=self;
lub
[textFieldName setDelegate:self];
Następnie użyj tego kodu, aby dopuścić tylko cyfry do pola tekstowego
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string { //return yes or no after comparing the characters // allow backspace if (!string.length) { return YES; } ////for Decimal value start//////This code use use for allowing single decimal value // if ([theTextField.text rangeOfString:@"."].location == NSNotFound) // { // if ([string isEqualToString:@"."]) { // return YES; // } // } // else // { // if ([[theTextField.text substringFromIndex:[theTextField.text rangeOfString:@"."].location] length]>2) // this allow 2 digit after decimal // { // return NO; // } // } ////for Decimal value End//////This code use use for allowing single decimal value // allow digit 0 to 9 if ([string intValue]) { return YES; } return NO; }
źródło
[string intValue]
zwraca 0 dla @ „0” - więcif ([string intValue])
nie jest spełnione dla @ „0”. Lepszy w użyciuif ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
@".".intValue
wynosi 0. I też@"0".intValue
wynosi 0.0
znaku zero ( ).Spróbuj tego, aby uniknąć problemu z czyszczeniem pól tekstowych
Swift 3.0
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { guard NSCharacterSet(charactersInString: "0123456789").isSupersetOfSet(NSCharacterSet(charactersInString: string)) else { return false } return true }
Swift 4.0
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string)) else { return false } return true }
źródło
return guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string))
Bardzo specyficzne kroki dla kodu Swift
Możesz zapewnić logikę ograniczającą dane wejściowe pola tekstowego w
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
metodzie, implementującUITextFieldDelegate
protokół.Dla jasności w tych krokach założono, że scenorys zawiera kontroler widoku z obiektem pola tekstowego, który powinien akceptować tylko cyfry.
Utwórz klasę niestandardową dla kontrolera widoku, który rozszerza
UIViewController
. Upewnij się, że scena w serii ujęć odnosi się do klasy niestandardowej, ustawiając wartość klasy niestandardowej w Inspektorze tożsamości Xcode.import UIKit class YourCustomController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } }
Utwórz wylot z pola tekstowego sceny do własnego kontrolera widoku.
class YourCustomController: UIViewController { @IBOutlet weak var numberField: UITextField! ... }
Zastosuj
UITextFieldDelegate
protokół w niestandardowym kontrolerze widoku.class YourCustomController: UIViewController, UITextFieldDelegate { ... }
W
viewDidLoad
metodzie kontrolera widoku niestandardowego przypisz delegata pola tekstowego do klasy kontrolera widoku niestandardowego.override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self }
Dodaj
UITextFieldDelegate
„sfunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
metody.W wyniku ustawienia
numberField
delegata niestandardowego kontrolera widoku jako delegata w poprzednim kroku, ta metoda będzie wywoływana za każdym razem, gdy użytkownik wprowadzi znak do pola tekstowego. Jeśli metoda powróci,true
znak pozostanie w polu tekstowym. Jeśli metoda powróci,false
znak nie pozostanie w polu tekstowym.string
Parametrem jest znak wprowadzanego przez użytkownika. Jeślistring
znak można zamienić na an,Int
to jest między 0 a 9; w przeciwnym razie jest to jakiś znak niebędący liczbą.class YourCustomController: UIViewController, UITextFieldDelegate { ... func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } }
(Zobacz poniżej pełny kod kontrolera).
Przykład kontrolera widoku z polem tekstowym zawierającym tylko cyfry
import UIKit class YourCustomController: UIViewController, UITextFieldDelegate { @IBOutlet weak var numberField: UITextField! override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { return Int(string) != nil } }
Przykładowy kontroler widoku z dziesiętnym polem tekstowym
Jeśli chcesz obsługiwać liczbę dziesiętną, skorzystaj z
NSNumberFormatter
. Zobacz komentarze do kodu dotyczące różnic.import UIKit class YourCustomController: UIViewController, UITextFieldDelegate { @IBOutlet weak var numberField: UITextField! private var formatter: NSNumberFormatter! override func viewDidLoad() { super.viewDidLoad() numberField.delegate = self // Initialize the formatter; minimum value is set to zero; style is Decimal. formatter = NSNumberFormatter() formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle formatter.minimum = 0 } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { // Combine the current text field value and the new string // character. If it conforms to the formatter's settings then // it is valid. If it doesn't then nil is returned and the // string character should not be allowed in the text field. return formatter.numberFromString("\(textField.text)\(string)") != nil } }
źródło
return string.toInt() != nil
Działał jak urok. Dzięki!return Int(string) != nil
return string == "" || Int(string) != nil
- (BOOL) textField: (UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string { NSNumberFormatter * nf = [[NSNumberFormatter alloc] init]; [nf setNumberStyle:NSNumberFormatterNoStyle]; NSString * newString = [NSString stringWithFormat:@"%@%@",textField.text,string]; NSNumber * number = [nf numberFromString:newString]; if (number) return YES; else return NO; }
źródło
Zastosowałem to i działa !!
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ // Check for non-numeric characters NSUInteger lengthOfString = string.length; for (NSInteger index = 0; index < lengthOfString; index++) { unichar character = [string characterAtIndex:index]; if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9 } // Check total length for restrict user NSUInteger proposedNewLength = textField.text.length - range.length + string.length; if (proposedNewLength > 6) return YES; return YES; }
źródło
if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9
zif ((character < 48 || character > 57) && character != 46)
Chciałbym dodatkowo zalecamy porównaćcharacter
do reprezentacji szesnastkowy liczb hexadecymalnie są najczęściej stosowane w tych okolicznościach. Tj.if ((character < 0x30 || character > 0x39) && character != 0x2E)
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet]; if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) { return NO; }
źródło
Works fine for me : - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound) && !(range.length==1 && string.length==0)) { return NO; } return YES; }
źródło
W Swift:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return string.isEmpty || Int(string) != nil }
źródło
szybki 5
//MARK:- UITextFieldDelegate func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let allowedCharacters = "1234567890" let allowedCharcterSet = CharacterSet(charactersIn: allowedCharacters) let typedCharcterSet = CharacterSet(charactersIn: string) return allowedCharcterSet.isSuperset(of: typedCharcterSet) }
Możesz teraz po prostu dotknąć tylko 1234567890
źródło
Zachowaj odrębne dane prezentacji od wewnętrznej reprezentacji. Jest prostszy sposób. Zróbmy
NSNumberFormatter
robotę:NSNumberFormatter* ns = [[NSNumberFormatter alloc] init]; ns.numberStyle = NSNumberFormatterDecimalStyle; [ns setMaximumFractionDigits:2]; // This is your internal representation of the localized number double a = [[ns numberFromString:self.textIVA.text] doubleValue]]; [mylabel setText:[NSString stringWithFormat:@"€ %@", [NSNumberFormatter localizedStringFromNumber: [NSNumber numberWithDouble:a] numberStyle:NSNumberFormatterDecimalStyle]]];
źródło
Jeśli używasz mojego wzorca specyfikacji, kod wygląda następująco
textField.delegate = self lazy var specification: Specification = { return RegularExpressionSpecification(pattern: "^(|0|[1-9]\\d{0,6})$") }() func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let textFieldString: NSString = textField.text ?? "" let s = textFieldString.stringByReplacingCharactersInRange(range, withString:string) return specification.isSatisfiedBy(s) } func textFieldShouldReturn(textField: UITextField) -> Bool { let s = textField.text ?? "" let isTextValid = specification.isSatisfiedBy(s) if isTextValid { textField.resignFirstResponder() } return false }
źródło
Zmodyfikowałem odpowiedź @ iDev na pracę z cyfrowymi i „.”:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ // Check for non-numeric characters NSUInteger lengthOfString = string.length; for (NSInteger index = 0; index < lengthOfString; index++) { unichar character = [string characterAtIndex:index]; if ((character < 48) && (character != 46)) return NO; // 48 unichar for 0, and 46 unichar for point if (character > 57) return NO; // 57 unichar for 9 } // Check for total length NSUInteger proposedNewLength = textField.text.length - range.length + string.length; if (proposedNewLength > 6) return YES; return YES; }
źródło
szybki 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField==yourTextFieldOutlet { if(CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: yourTextFieldOutlet.text!))){ //if numbers only, then your code here } else{ showAlert(title: "Error",message: "Enter Number only",type: "failure") } } return true }
źródło
Użyj tego kodu:
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string]; NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet]; if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) { return NO; }
źródło