Textfield проверка на цифры иначе ошибка swift

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

Mark Meretzky's user avatar

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

FRIDDAY's user avatar

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

Phạm Đông's user avatar

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

Boudz78's user avatar

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 Dabus's user avatar

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

glace's user avatar

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

Lumialxk's user avatar

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!)

Speed Limit 55 signage on road

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, из которого вы получаете эти значения, вы можете указать тип клавиатуры, которую вы хотите видеть, когда кто-то касается текстового поля.

Например, цифровая клавиатура.

Понравился этот скриншот:

Изображение 108130

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Как мне сопоставить динамический маршрут в базе данных?

Понравилась статья? Поделить с друзьями:
  • Text ru проверка текста на ошибки
  • Text ru проверить текст на ошибки
  • Texmod ошибка d oh
  • Texmod выдает ошибку d oh
  • Texet ошибка камеры