My iOS SwiftUI TextField allows the user to input an Int. If the user types bad input characters such as «abc» instead of «123», I would like to display the bad characters in an error message in my Text (where I wrote textField.text), and I would like to keep the TextField’s keyboard on the screen until the user provides correct input. How to make this happen? Thank you in advance. Xcode 11.6 on macOS Catalina 10.15.6.
struct ContentView: View {
@State private var value: Int? = nil;
@State private var text: String = "";
var body: some View {
VStack {
TextField(
"Enter an integer:",
value: $value,
formatter: NumberFormatter(),
onCommit: {
guard let value: Int = self.value else {
self.text = "Bad input \"\(textField.text)\".";
//Do not dismiss the TextField's keyboard.
return;
}
//Dismiss the TextField's keyboard.
self.text = "The product is \(2 * value).";
}
)
.keyboardType(.numbersAndPunctuation)
.textFieldStyle(RoundedBorderTextFieldStyle())
Text(text)
}
.padding([.leading, .trailing], 16)
}
}
asked Aug 17, 2020 at 12:08
1
Below code gives you an idea for validating your text inside the textfield while user is typing.
struct ContentView: View {
@State private var textNumber : String = ""
@State private var isNumberValid : Bool = true
var body: some View {
VStack {
TextField("Enter an integer:", text: numberValidator())
.keyboardType(.numbersAndPunctuation)
.textFieldStyle(RoundedBorderTextFieldStyle())
if !self.isNumberValid {
Text("Bad input \"\(textNumber)\".")
.font(.callout)
.foregroundColor(Color.red)
}
}
.padding([.leading, .trailing], 16)
}
private func numberValidator() -> Binding<String> {
return Binding<String>(
get: {
return self.textNumber
}) {
if CharacterSet(charactersIn: "1234567890").isSuperset(of: CharacterSet(charactersIn: $0)) {
self.textNumber = $0
self.isNumberValid = true
} else {
self.textNumber = $0
//self.textNumber = ""
self.isNumberValid = false
}
}
}
}
answered Aug 17, 2020 at 15:48
FRIDDAYFRIDDAY
3,8011 gold badge29 silver badges43 bronze badges
The following code snippet gives you an idea to validate your text inside the text field as the user is typing using Get, Set value
let checkValue = Binding<String>(
get: {
self.value
},
set: {
self.value = $0
}
)
I hope it can be of help to you
struct ContentView: View {
@State private var value: String = ""
@State private var text: String = ""
var body: some View {
let checkValue = Binding<String>(
get: {
self.value
},
set: {
self.value = $0
}
)
return VStack {
TextField("Enter an integer:",text: checkValue)
.keyboardType(.numbersAndPunctuation)
.textFieldStyle(RoundedBorderTextFieldStyle())
Text("Bad interger: \(Int(self.value) != nil ? "" : self.value)").foregroundColor(Color.red)
}
.padding([.leading, .trailing], 16)
}
}
answered Aug 18, 2020 at 9:44
How can i check through an if-statement if a TextField is an integer or not ?
@IBAction func Clickme2(sender: AnyObject) {
if TextField2.text == Int() {
}
asked Apr 8, 2016 at 5:42
0
You can check it the textField text property is not nil and if it can be converted to Int:
guard let text = textField2.text, integer = Int(text) else { return }
print(integer)
If you just need to know if it text property has an Integer you can create a computed property to return true or false as follow:
extension UITextField {
var isInteger: Bool {
guard let text = text else { return false }
return Int(text) != nil
}
}
usage:
if textField2.isInteger {
// do whatever
}
answered Apr 8, 2016 at 5:58
Leo DabusLeo Dabus
230k59 gold badges489 silver badges571 bronze badges
if ( Int(textField2.text) == nil) {
//In this case, your text is not an integer
}
This works perfectly fine since Swift has those fancy failable Initializers which prevent your app from crashing when you pass invalid parameters
answered Apr 8, 2016 at 6:01
glaceglace
2,1621 gold badge17 silver badges23 bronze badges
0
If you want to check » 1 2 3 » as int,you can do like this:
@IBAction func Clickme2(sender: AnyObject) {
var text = TextField2.text.stringByReplacingOccurrencesOfString(" ", withString: "")
if let integer = Int(text) {
// do something here
}
}
If you only want to check » 123 » as int,you can do like this:
@IBAction func Clickme2(sender: AnyObject) {
var text = TextField2.text.stringByTrimmingCharactersInSet(.whitespaceCharacterSet())
if let integer = Int(text) {
// do something here
}
}
answered Apr 8, 2016 at 6:41
LumialxkLumialxk
6,2496 gold badges24 silver badges47 bronze badges
If you are looking for validation
in the swift programming language
then you are on the right search. Swift language input validation
may be a different kind like username
, name
, phone number
, email address
and much more, but you do not need to worry about that. Because if you know the procedure of validation
then you can do any kind of validation
. Here I am going to tell you two
different kind of UITextField validation
. One will be done on click of the button
and another will be done at the time of entering the input into UITextField
.
Let’s take an example of Indian Mobile Number validation
with digits and it’s length.
1. Way one on button action : If you want to validate the number
after click on button then run the following function for the result.
func mobile_number(string : String) -> Bool {
var is_check : Bool
let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
let compSepByCharInSet = string.components(separatedBy: aSet)
let numberFiltered = compSepByCharInSet.joined(separator: "")
is_check = string == numberFiltered
if is_check {
if string.count != 10 {
is_check = false
}
}
return is_check
}
if returning is true
then number is valid else number is invalid.
2. Now let’s see the another way : If you want to validate the phone number at the time of entering the input then you need to set the delegate
to the input field. So write a single line in your viewDidLoad()
method.
yourTextField.delegate = self
You have done with the main function now add an extension
to your current class and extend UITextFieldDelegate
.
extension MyMainClass : UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == yourTextField { var is_check : Bool let aSet = NSCharacterSet(charactersIn:"0123456789").inverted let compSepByCharInSet = string.components(separatedBy: aSet) let numberFiltered = compSepByCharInSet.joined(separator: "") is_check = string == numberFiltered if is_check { let maxLength = 10 let currentString: NSString = textField.text! as NSString let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString is_check = newString.length <= maxLength } return is_check }else { return true } } }
shouldChangeCharactersIn
is the abstract function which is called by default on every input, and if it returns true then the input is authorized
else not authorized
.
Now let’s take an example of REGX
validation. Here I am showing you an example of email validation
function.
func validateEmail(email:String) -> Bool {
let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}" // this is the REGX
let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
return emailPredicate.evaluate(with: email)
}
This function is only for email validation in swift
language. In the sam way you can validate different type of REGX (Regular expression)
.
Wish you good luck 🙂 Happy Coding
Tags
About The Author
Pushpendra Kumar
I am passionate about mobile application development and professional developer at Colour Moon Technologies Pvt Ltd (www.thecolourmoon.com). This website I have made so that I can meet with new challenges and can share here.
You are viewing an archived post.
Contents of this post may no longer be relevant or work as described.
Apple only provides UITextField for inputs which always returns a string. You can define a keyboard layout (decimal pad in my case) but that is where support for numeric inputs in iOS ends.
Today I’m going to show you how to limit the characters a user can enter and verify we actually have a number. (Hint: Don’t trust the chosen keyboard layout! The user can copy/paste). With the decimal pad keyboard the user can enter strings like 32,241,241,1,1
or 23.13.1.
neither of which are legit numbers, let alone monetary.
I’ll show you how to create a text input which only allows valid decimal numbers and limits the amount of decimal places. With locale specific variations in mind: 5.5
in the US is equal to 5,5
in Germany for example, and our app should support both.
I assume you already have a UITextField in your storyboard. Make sure you have the keyboard type set to Decimal Pad
either in the storyboard or in code and connected the outlet to your ViewController. The first thing we have to do now is declare our ViewController as textfield delegate:
// ViewController.swift
// Make sure our ViewController is a UITextFieldDelegate
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var moneyTextField: UITextField!
override func viewDidLoad() {
// Declare ourself as textfield delegate
moneyTextField.delegate = self
}
}
Here we add the UITextFieldDelegate
protocol to our class and set the moneyTextField.delegate
to the viewController (self)
.
Now to the actual validation by implementing the textField(shouldChangeCharactersIn:)
method. This method runs every time the user modifies the text in any way (typing, deleting, pasting) and before the UI reflects the changes.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// User pressed the delete-key to remove a character, this is always valid, return true to allow change
if string.isEmpty { return true }
// Build the full current string: TextField right now only contains the
// previous valid value. Use provided info to build up the new version.
// Can't just concat the two strings because the user might've moved the
// cursor and delete something in the middle.
let currentText = textField.text ?? ""
let replacementText = (currentText as NSString).replacingCharacters(in: range, with: string)
// Use our string extensions to check if the string is a valid double and
// only has the specified amount of decimal places.
return replacementText.isValidDouble(maxDecimalPlaces: 2)
}
Here we build what the new string would look like as replacementText
and then use my own String
extension isValidDouble(maximalDecimalPlaces:)
to verify the input. I’m using an extension because I have many places where I need to perform this check. If you only accept number inputs in this place and nowhere else feel free to move the code into the method above.
Quick explanation for shouldChangeCharactersIn:
: If you return true then iOS updates the textField value with the changes the user performed. But if you return false the changes get dropped and nothing happens.
Here is the extension implementation performing the actual checks:
extension String {
func isValidDouble(maxDecimalPlaces: Int) -> Bool {
// Use NumberFormatter to check if we can turn the string into a number
// and to get the locale specific decimal separator.
let formatter = NumberFormatter()
formatter.allowsFloats = true // Default is true, be explicit anyways
let decimalSeparator = formatter.decimalSeparator ?? "." // Gets the locale specific decimal separator. If for some reason there is none we assume "." is used as separator.
// Check if we can create a valid number. (The formatter creates a NSNumber, but
// every NSNumber is a valid double, so we're good!)
if formatter.number(from: self) != nil {
// Split our string at the decimal separator
let split = self.components(separatedBy: decimalSeparator)
// Depending on whether there was a decimalSeparator we may have one
// or two parts now. If it is two then the second part is the one after
// the separator, aka the digits we care about.
// If there was no separator then the user hasn't entered a decimal
// number yet and we treat the string as empty, succeeding the check
let digits = split.count == 2 ? split.last ?? "" : ""
// Finally check if we're <= the allowed digits
return digits.characters.count <= maxDecimalPlaces // TODO: Swift 4.0 replace with digits.count, YAY!
}
return false // couldn't turn string into a valid number
}
}
First we create a NumberFormatter, a locale aware way to get numbers from Strings and ask it for the decimal separator. We then try to create a number from the string. When that succeeds we check if the number of decimal places is less than or equal to the provided. If everything checks out we return true at which point the UI updates with the modifications to the textField.
Now we have a textField input that only accepts valid numbers, respects locale specific decimal separators and limits the number of decimal places to whatever we want.
The user can never enter a non-valid number, not even by pasting in some garbage and once they’re ready to save you can be sure it is valid. (Of course the textField can still be empty!)
33 ответа
Вот мои 2 цента. (проверено только на Swift 2)
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let aSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
let compSepByCharInSet = string.componentsSeparatedByCharactersInSet(aSet)
let numberFiltered = compSepByCharInSet.joinWithSeparator("")
return string == numberFiltered
}
Это немного более строго. Также нет десятичной точки.
Надеюсь, что это поможет:)
PS: Я предположил, что вы все равно следили за делегатом.
Обновление: Swift 3.0:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let aSet = NSCharacterSet(charactersIn:"0123456789").inverted
let compSepByCharInSet = string.components(separatedBy: aSet)
let numberFiltered = compSepByCharInSet.joined(separator: "")
return string == numberFiltered
}
Mr H
Поделиться
Решение для быстрого 3.0 и выше
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let allowedCharacters = CharacterSet.decimalDigits
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
Hiren Panchal
Поделиться
Swift 2.0
Только для номеров и одного номера. десятичное значение в поле uitext.
func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString string: String) -> Bool
{
let newCharacters = NSCharacterSet(charactersInString: string)
let boolIsNumber = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
if boolIsNumber == true {
return true
} else {
if string == "." {
let countdots = textField.text!.componentsSeparatedByString(".").count - 1
if countdots == 0 {
return true
} else {
if countdots > 0 && string == "." {
return false
} else {
return true
}
}
} else {
return false
}
}
}
Cian
Поделиться
В swift 4.1 и Xcode 9.4.1
Добавьте UITextFieldDelegate в свой класс
class YourViewController: UIViewController, UITextFieldDelegate
Затем напишите этот код в вашем viewDidLoad()
mobileNoTF.delegate = self
Написать эту делегатную функцию текстового поля
//MARK - UITextField Delegates
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//For mobile numer validation
if textField == mobileNoTF {
let allowedCharacters = CharacterSet(charactersIn:"+0123456789 ")//Here change this characters based on your requirement
let characterSet = CharacterSet(charactersIn: string)
return allowedCharacters.isSuperset(of: characterSet)
}
return true
}
iOS
Поделиться
Принять десятичные значения в текстовых полях с одной (.) точкой в Swift 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
if filtered == string {
return true
} else {
if string == "." {
let countdots = textField.text!.components(separatedBy:".").count - 1
if countdots == 0 {
return true
}else{
if countdots > 0 && string == "." {
return false
} else {
return true
}
}
}else{
return false
}
}
}
Raj Joshi
Поделиться
В любом UITextField, из которого вы получаете эти значения, вы можете указать тип клавиатуры, которую вы хотите видеть, когда кто-то касается текстового поля.
Например, цифровая клавиатура.
Понравился этот скриншот:
Jamil Hasnine Tamim
Поделиться
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// return true if the replacementString only contains numeric characters
let digits = NSCharacterSet.decimalDigitCharacterSet()
for c in string {
if !digits.characterIsMember(c) {
return false
}
}
return true
}
Это решение будет работать, даже если пользователь переключит клавиатуру или попытается вставить нечисловую строку в текстовое поле.
Обязательно установите для свойства delegate
соответствующее текстовое поле.
ndmeiri
Поделиться
Вот простое решение, вам нужно подключить событие «Редактирование изменено» к этому методу в вашем контроллере
Swift 4
@IBAction func valueChanged(_ sender: UITextField) {
if let last = sender.text?.last {
let zero: Character = "0"
let num: Int = Int(UnicodeScalar(String(last))!.value - UnicodeScalar(String(zero))!.value)
if (num < 0 || num > 9) {
//remove the last character as it is invalid
sender.text?.removeLast()
}
}
}
shbli
Поделиться
Использовать форматирование чисел
Swift 4.x
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let s = NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string)
guard !s.isEmpty else { return true }
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .none
return numberFormatter.number(from: s)?.intValue != nil
}
SPatel
Поделиться
Расширьте свой контроллер представлений следующим образом:
class MyViewController: UIViewController, UITextFieldDelegate
Функция viewDidLoad распространяется на текстовое поле следующим образом:
myTextField.delegate = self
Затем используйте следующую функцию:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let isNumber = CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: string))
let withDecimal = (
string == NumberFormatter().decimalSeparator &&
textField.text?.contains(string) == false
)
return isNumber || withDecimal
}
Теперь вы убедитесь, что пользователь может ввести только десятичные цифры.
Swift 4 + принимает только номер и принимает один разделитель
Aftab Ahmed
Поделиться
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let numRange = string.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet()) {
return false
} else {
return true
}
}
likarson
Поделиться
В то время как большинство из этих решений будут работать, имейте в виду, что в некоторых локализациях десятичные знаки разделяются символом «,», а не «.»
Более чистый способ сделать это будет
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let decimalCharacter = NSNumberFormatter().decimalSeparator
let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
characterSet.addCharactersInString(decimalCharacter)
return replacementString.rangeOfCharacterFromSet(characterSet.invertedSet) == nil
}
AlexLittlejohn
Поделиться
Протестировано в swift 3.0
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
let numberOnly = NSCharacterSet.init(charactersIn: "0123456789")
let stringFromTextField = NSCharacterSet.init(charactersIn: string)
let strValid = numberOnly.isSuperset(of: stringFromTextField as CharacterSet)
return strValid
}
iosLearner
Поделиться
Я действительно сделал это, работая над книгой Big Nerd Ranch, мое решение:
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
let newCharacters = NSCharacterSet(charactersInString: string)
return NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newCharacters)
}
это позволяет только номера 0-9, чтобы разрешить «.» также сложнее, поскольку вы можете разрешить только один. «
sgib
Поделиться
1-й, вы должны наследовать класс UITextFieldDelegate с собственным классом
class ViewController: UIViewController, UITextFieldDelegate {
2-й добавить IBOutlet
@IBOutlet weak var firstName: UITextField!
В-третьих, вы должны убедиться, что этот объект использует
override func viewDidLoad() {
super.viewDidLoad()
firstName.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == firstName {
let allowedCharacters = "1234567890"
let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
let typedCharacterSet = CharacterSet(charactersIn: string)
let alphabet = allowedCharacterSet.isSuperset(of: typedCharacterSet)
return alphabet
}
}
akbar khan
Поделиться
Я редактировал версию Raj Joshi, чтобы разрешить одну точку или одну запятую:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let inverseSet = CharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
if filtered == string {
return true
} else {
if string == "." || string == "," {
let countDots = textField.text!.components(separatedBy:".").count - 1
let countCommas = textField.text!.components(separatedBy:",").count - 1
if countDots == 0 && countCommas == 0 {
return true
} else {
return false
}
} else {
return false
}
}
}
Matthijs
Поделиться
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let textString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
if textField == self.phoneTextField && string.characters.count > 0{
let numberOnly = NSCharacterSet.decimalDigits
let strValid = numberOnly.contains(UnicodeScalar.init(string)!)
return strValid && textString.characters.count <= 10
}
return true
}
в приведенном выше коде работает быстро 3
NSCharacterSet. ДесятичныхЦифрах
Вы также используете буквы только
NSCharacterSet. Письма
и верхний регистр, нижний регистр, буквенно-цифровые символы, пробелы
используется тот же код
или См. ссылку
Ramprasath Selvam
Поделиться
Ниже приведен код, который я использовал в Swift 3.0, адаптированный из кода г-на H. Различия в том, что:
a) В Swift 3.0 было изменено объявление функции делегата. Новая декларация здесь
b) Объявление NSCharacterSet изменилось.
func textField(_ shouldChangeCharactersIntextField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
return string == filtered
}
ChinLoong
Поделиться
Чтобы разрешить только числа и только один десятичный оператор, вы можете использовать это решение:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let isNumber = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(NSCharacterSet(charactersInString: string))
return isNumber || (string == NSNumberFormatter().decimalSeparator && textField.text?.containsString(string) == false)
}
hprione
Поделиться
Как будто ответов недостаточно, вот мой. Я думаю, что каждый пример, разрешенный для десятичных разделителей, имеет недостатки в локализации, обратном пространстве или копировании/вставке.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if string.isEmpty {return true} //allow for backspace
let decimalSeparator = NSNumberFormatter().decimalSeparator ?? "."
let validChars = NSMutableCharacterSet(charactersInString: decimalSeparator)
validChars.formUnionWithCharacterSet(NSCharacterSet.decimalDigitCharacterSet())
if validChars.isSupersetOfSet(NSCharacterSet(charactersInString: string)){
switch string.componentsSeparatedByString(decimalSeparator).count-1 {
case 0: //no decimals
return true
case 1: //if adding decimal, only allow if no existing decimal
if let existingText = textField.text{
return existingText.componentsSeparatedByString(decimalSeparator).count <= 1
}
else {return true}
default: //invalid decimals
return false
}
}
return false
}
David
Поделиться
Я думаю, вы можете заставить изменить тип клавиатуры, выполнив протокол UITextInputTraits, необязательный var keyboardType
//class ViewController: UIViewController, UITextInputTraits {
@IBOutlet weak var textFieldKeyboardType: UITextField!{
didSet{
textFieldKeyboardType.keyboardType = UIKeyboardType.NumberPad
}
}
var keyboardType: UIKeyboardType {
get{
return textFieldKeyboardType.keyboardType
}
set{
if newValue != UIKeyboardType.NumberPad{
self.keyboardType = UIKeyboardType.NumberPad
}
}
}
Lukas
Поделиться
Вот более чистое решение:
guard CharacterSet(charactersIn: "123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
return false
}
return true
Для десятичных дробей просто добавьте .
Пример 123456789.
Farhad
Поделиться
Для разрешения некоторых характеристик
func CheckAddress(string:String) -> Bool {
let numberOnly = NSCharacterSet.init(charactersIn: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-@,&#/")
let stringFromTextField = NSCharacterSet.init(charactersIn: string)
return numberOnly.isSuperset(of: stringFromTextField as CharacterSet)
}
print("\(CheckAddress(string: "123"))") //True
print("\(CheckAddress(string: "asdf-"))") //True
print("\(CheckAddress(string: "asd123$"))") //false
Ilesh
Поделиться
Swift 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
}
ArgaPK
Поделиться
Этот код можно использовать, если вы хотите разрешить десятичный разделитель и/или отрицательные числа.
Но этот код позволяет: «34». (десятичный разделитель в конце) при изменении текста. Поэтому вам нужно добавить пример кода: функции textFieldShouldReturn или textFieldShouldEndEditing делегата.
Код, написанный в Swift 4, но я согласен, что это совместимо с Swift 3.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else {
return true
}
let replaced = (text as NSString).replacingCharacters(in: range, with: string)
let decimalSeparator = NSLocale.current.decimalSeparator ?? ""
// When user wants to delete las character
if replaced == "" || replaced == "-" || replaced == "-0" {
textField.text = "0"
return false
}
// When text contains 0 before replace except "0."
if replaced != "0" + decimalSeparator && replaced.hasPrefix("0") && text.underestimatedCount == 1 {
textField.text = replaced.substring(from: replaced.index(after: replaced.startIndex))
return false
}
// When user wants to delete minus sign
if text.hasPrefix("-") && text.substring(from: text.index(after: text.startIndex)) == replaced {
return false
}
// When user wants to delete before decimal separator
if replaced.hasPrefix(decimalSeparator) || replaced.hasPrefix("-" + decimalSeparator) {
return false
}
// When user wants to add zero the beginning of number... but allowing "0." or "-0." numbers
let testReplaced = replaced.hasPrefix("-") ? replaced.substring(from: replaced.index(after: replaced.startIndex)) : replaced
if testReplaced.count >= 2 && testReplaced.hasPrefix("0") && !testReplaced.hasPrefix("0" + decimalSeparator) {
return false
}
// Every other cases
let allowDecimal = self.allowFloat ? (decimalSeparator == "." ? "\\.?" : decimalSeparator + "?") : ""
let allowSign = self.allowSigned ? "-?" : ""
let pattern = "\(allowSign)[0-9]+\(allowDecimal)([0-9]+)?"
do {
let regexRange = (replaced as NSString).range(of: replaced)
let regex = try NSRegularExpression(pattern: pattern, options: [])
let matches = regex.matches(in: replaced, options: [], range: regexRange)
return matches.count == 1 && matches.first!.range == regexRange
}
catch {}
return false
}
Если вы не хотите разрешать десятичные или отрицательные числа, вам нужно заменить переменную буксировки следующей строкой
let allowDecimal = ""
let allowSign = ""
Ferenc Kiss
Поделиться
Мертвое простое решение для чисел Double
(имейте в виду, что это не лучшее удобное для пользователя решение), в вашем делегате UITextFieldDelegate
:
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
guard let currentString = textField.text as NSString? else {
return false
}
let newString = currentString.replacingCharacters(in: range, with: string)
return Double(newString) != nil
}
Tomasz Wójcik
Поделиться
Вы можете использовать shouldChangeCharactersInRange вместе со способом расширения String, чтобы проверить, является ли строка ввода номером или нет.
extension String {
var isNumber : Bool {
get{
return !self.isEmpty && self.stringWithoutWhitespaces.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}
}
var stringWithoutWhitespaces: String {
return self.replacingOccurrences(of: " ", with: "")
}
}
//Mark: shouldChangeCharactersInRange
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// return true if the string only contains numeric characters
let isValid = string.stringWithoutWhitespaces.isNumber
return valid
}
Suhit Patil
Поделиться
func isValidNumber(str:String) -> Bool{
if str.isEmpty {
return false
}
let newChar = NSCharacterSet(charactersInString: str)
let boolValid = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(newChar)
if boolValid{
return true
}else{
let lst = str.componentsSeparatedByString(".")
let newStr = lst.joinWithSeparator("")
let currentChar = NSCharacterSet(charactersInString: newStr)
if lst.count == 2 && !lst.contains("") && NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(currentChar){
return true
}
return false
}
}
Поместите эту функцию в метод «Отправить» или «Сохранить», если она есть.
den330
Поделиться
Это более читаемая версия, которая будет делать «0-9» плюс «.»:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let existingTextHasDecimal = textField.text?.rangeOfString(".")
let replacementTextHasDecimal = string.rangeOfString(".")
let replacementTextAllCharacters = NSCharacterSet(charactersInString: string)
let replacementTextOnlyDigits = NSCharacterSet.decimalDigitCharacterSet().isSupersetOfSet(replacementTextAllCharacters)
if replacementTextHasDecimal != nil && existingTextHasDecimal != nil {
return false
}else{
if replacementTextOnlyDigits == true {
return true
}else if replacementTextHasDecimal != nil{
return true
}else{
return false
}
}
}
Enraged
Поделиться
Swift 2.0
func textField(textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
replacementString string: String) -> Bool {
let inverseSet = NSCharacterSet(charactersInString:"0123456789").invertedSet
let components = string.componentsSeparatedByCharactersInSet(inverseSet)
let filtered = components.joinWithSeparator("")
return string == filtered
}
tymac
Поделиться
Сначала добавьте delegate
и keyBoradType
из textField
textField.delegate=self;
textField.keyboardType = UIKeyboardTypeNumberPad;
Чем нужно использовать метод textField.delegate
так:
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString: (NSString *)string
{
if (!string.length)
{
return YES;
}
if ([string intValue])
{
return YES;
}
return NO;
}
Harvant S. Choudhary
Поделиться
//Принимать только десятичные числа в качестве входных данных, [SWIFT 3.0]
func textField(_ shouldChangeCharactersIntextField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
let inverseSet = NSCharacterSet(charactersIn:"0123456789").inverted
let components = string.components(separatedBy: inverseSet)
let filtered = components.joined(separator: "")
return string == filtered
}
Siddharth Kavthekar
Поделиться
Обновлен ответ Сиана выше на Swift 3:
func textField(textField: UITextField,shouldChangeCharactersInRange range: NSRange,replacementString string: String) -> Bool
{
let newCharacters = NSCharacterSet(charactersIn: string)
let boolIsNumber = NSCharacterSet.decimalDigits.isSuperset(of:newCharacters as CharacterSet)
if boolIsNumber == true {
return true
} else {
if string == "." {
let countdots = textField.text!.components(separatedBy:".").count - 1
if countdots == 0 {
return true
} else {
if countdots > 0 && string == "." {
return false
} else {
return true
}
}
} else {
return false
}
}
}
Jay
Поделиться
Ещё вопросы
- 0Объект, два выпадающих списка, ng-options и привязка значения
- 1Как добавить ‘-‘ в YAML, используя словарь / JSON?
- 0ЗАГРУЗКА ДАННЫХ INFILE с удаленного сервера при получении ошибки
- 1слушатель push-уведомлений sw-precache
- 0Как я могу добавить переменную php в javascript?
- 1Теория позади изображения вычитает 0,5, а затем умножает на 2
- 0Как реализовать одно и то же действие с переходом и без перехода?
- 0Как отсортировать набор по разыменованным значениям? [Дубликат]
- 0Удаленное подключение к MySQL на EC2 без SSH-туннелирования
- 0HTML-тег div слева, свойства правого поля работают по-разному для разных браузеров
- 0тип начала эффекта (HTML, CSS, JQUERY)
- 1Получите оптимальный размер предварительного просмотра видео для высокоскоростной видеосессии
- 0Удаление файла из папки
- 0Javascript скрипты замедляются до нуля
- 1Исключение, которое выдается, когда переменные экземпляра равны нулю
- 1Надувной замок: отдельные изменения подписи в конвертах при каждом запуске
- 1Как открыть конкретный экран после нажатия на уведомление?
- 0держать меню JavaScript открытым при загрузке новой страницы
- 1Google 59 больше не поддерживает встроенные учетные данные
- 0Как отобразить строку как дату? [Дубликат]
- 1Определить предмет, объект, глагол в английском предложении?
- 1Я не могу использовать более одного шрифта в Pygame
- 0не уверены в результате запроса
- 1Как передать значение свойства в метод init в SAPUI5?
- 0mmap и выравнивание страниц данных — это увеличивает производительность?
- 0Изменить несколько элементов с помощью PHP
- 1Java выбирает txt файл и использует строку insaid в функции
- 1EditText странное поведение фокуса
- 1Кодированный пользовательский интерфейс UITestControlCollection в массив
- 1Невозможно создать версионный API в SailJS
- 1Ошибка в библиотеке, созданной с помощью jitpack: невозможно разрешить зависимость для ‘: app @ debug / compileClasspath’
- 0libssh2_config.h не создается при установке libssh2
- 0У меня ошибка LNK2019: нерешенная внешняя ошибка символа (небольшой код для просмотра)
- 0Причина, почему оператор = обычно возвращает ссылку на объект в C ++?
- 0Ошибка сегментации: 11 при использовании форсированного мьютекса
- 1Как я могу пройти и сократить объект?
- 1Правильный способ передачи ошибок обратно в вызывающий код
- 0Как анимировать div слева направо, нажав на ссылку?
- 1LINQ Выберите заявление. Анонимный метод возвращает исключение
- 0Как показать содержимое файла журнала в новом окне, когда мы нажимаем на ссылку весной mvc
- 1Отделение целочисленных значений от строки
- 1Почему эта нарезка бросает IndexError?
- 0Завершение соединения MySQL
- 1Создать строку из n символов без цикла [duplicate]
- 1Хадсон не запускается
- 0Ошибка компиляции PHP при создании представлений и контроллеров с использованием Gii в YII2
- 0Центрировать элемент Div на странице?
- 1Во время вызова OnActionExecuting for Web API — Как сопоставить контроллер / класс действия из строки маршрута для чтения атрибутов действия
- 1Запустите одно приложение метро из другого приложения метро Windows 8
- 0Как мне сопоставить динамический маршрут в базе данных?