iPad에는 iPhone / iPod처럼 "Numpad"키보드가 없습니다.
0에서 9까지의 값만 허용하도록 사용자의 키보드를 제한 할 수있는 방법을 찾고 있습니다.
UITextField의 "shouldChangeCharactersInRange"를 사용하는 것을 상상하지만이를 구현하는 가장 좋은 방법을 모르겠습니다.
iPad에는 iPhone / iPod처럼 "Numpad"키보드가 없습니다.
0에서 9까지의 값만 허용하도록 사용자의 키보드를 제한 할 수있는 방법을 찾고 있습니다.
UITextField의 "shouldChangeCharactersInRange"를 사용하는 것을 상상하지만이를 구현하는 가장 좋은 방법을 모르겠습니다.
답변:
이것이 SSN 확인 필드에서 문제를 처리하는 방법이며, 최대 길이를 수정하고 if
필요한 경우 키보드 유형을 확인 하는 문을 제거 할 수 있습니다.
데이터를 붙여 넣는 대신 사용자가 입력 할 때 최대 길이 경고를 억제하는 논리도 있습니다.
이 코드의 컨텍스트 내에서 전달 된 메시지 문자열을 사용하여 presentAlert()/presentAlert:
a UIAlertController
(또는 레거시 UIAlertView
)를 표시하는 몇 가지 기본 함수가 있습니다.
// 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
}
// 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;
}
이 코드를 사용하여 textField에서 숫자 만 허용 할 수 있습니다.
textField에 대한 대리자를 설정하기 전에
textFieldName.delegate=self;
또는
[textFieldName setDelegate:self];
이 코드를 사용하여 textField에 숫자 만 허용하십시오.
- (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;
}
[string intValue]
경우 @ "0"에 대해 0을 반환하므로 if ([string intValue])
@ "0"에 대해 충족되지 않습니다. 더 나은 사용if ([string rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)
@".".intValue
0입니다. 또한 @"0".intValue
0입니다.
0
) 문자를 입력 할 수 없도록 합니다.
텍스트 필드 지우기 문제를 방지하려면 이것을 시도하십시오.
스위프트 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
}
스위프트 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
}
return guard CharacterSet(charactersIn: "0123456789").isSuperset(of: CharacterSet(charactersIn: string))
Swift 코드에 대한 매우 구체적인 단계
프로토콜 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
을 구현하여 메서드 에서 텍스트 필드의 입력을 제한하는 논리를 제공 할 수 있습니다 UITextFieldDelegate
.
명확성을 위해이 단계에서는 스토리 보드에 숫자 만 허용해야하는 텍스트 필드 개체 가있는 View Controller 가 포함되어 있다고 가정합니다 .
확장하는 뷰 컨트롤러에 대한 사용자 정의 클래스를 만듭니다 UIViewController
. Xcode의 Identity Inspector에서 사용자 정의 클래스 값을 설정하여 스토리 보드의 장면이 사용자 정의 클래스를 참조 하는지 확인하십시오 .
import UIKit
class YourCustomController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
장면의 텍스트 필드에서 사용자 정의 뷰 컨트롤러로의 콘센트를 만듭니다.
class YourCustomController: UIViewController {
@IBOutlet weak var numberField: UITextField!
...
}
UITextFieldDelegate
사용자 정의보기 컨트롤러에 프로토콜을 적용하십시오 .
class YourCustomController: UIViewController, UITextFieldDelegate {
...
}
커스텀 뷰 컨트롤러의 viewDidLoad
메서드에서 텍스트 필드의 델리게이트를 커스텀 뷰 컨트롤러 클래스에 할당합니다.
override func viewDidLoad() {
super.viewDidLoad()
numberField.delegate = self
}
UITextFieldDelegate
의 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
메소드를 추가하십시오 .
numberField
이전 단계에서 사용자 정의 뷰 컨트롤러를 의 대리자 로 만든 결과 사용자가 텍스트 필드에 문자를 입력 할 때마다이 메서드가 호출됩니다. 메서드가 반환 true
되면 문자가 텍스트 필드에 남아 있습니다. 메서드가 반환 false
되면 문자가 텍스트 필드에 남아 있지 않습니다 .
string
매개 변수는 사용자에 의해 입력되는 문자이다. string
문자를로 변환 할 수있는 경우 Int
0에서 9 사이입니다. 그렇지 않으면 숫자가 아닌 문자입니다.
class YourCustomController: UIViewController, UITextFieldDelegate {
...
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
return Int(string) != nil
}
}
(전체보기 컨트롤러 코드는 아래를 참조하세요.)
숫자 만있는 텍스트 필드가있는보기 컨트롤러의 예
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
}
}
10 진수 텍스트 필드가있는보기 컨트롤러 예
십진수를 지원하려면 NSNumberFormatter
. 차이점은 코드 주석을 참조하십시오.
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
}
}
return string.toInt() != nil
매력처럼 작동했습니다. 감사!
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;
}
나는 이것을 적용하고 작동합니다 !!
-(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;
}
if (character < 48) return NO; // 48 unichar for 0 if (character > 57) return NO; // 57 unichar for 9
와 if ((character < 48 || character > 57) && character != 46)
추가로 비교할 추천 할 것입니다 I character
헥사 가장 일반적으로 이러한 상황에서 사용되는 같은 숫자의 16 진수 표현에. Ieif ((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;
}
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;
}
스위프트 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)
}
이제 1234567890 만 탭하면됩니다.
내부 표현과 구별되는 프레젠테이션 데이터를 유지합니다. 더 간단한 방법이 있습니다. 일을하자 NSNumberFormatter
:
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]]];
내 사양 패턴 을 사용하면 코드는 다음과 같습니다.
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
}
디지털 작업 및 "."에 대한 @iDev의 답변을 수정했습니다.
-(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;
}
스위프트 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
}
이 코드를 사용하십시오.
NSString* val = [[textField text] stringByReplacingCharactersInRange:range withString:string];
NSCharacterSet *allowedCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
if ([[string componentsSeparatedByCharactersInSet:[allowedCharacterSet invertedSet]] count] > 1 || [val length] > 5) {
return NO;
}