it-swarm.com.ru

Какое поле может содержать только целое число?

В Swift я пытаюсь создать текстовое поле, которое позволит включить кнопку, но только когда текстовое поле содержит целое число. Как я могу это сделать?

20
user4241521
  1. Сделайте ваш контроллер представления UITextFieldDelegate, добавив UITextFieldDelegate в объявление класса.
  2. Добавьте IBOutlets для своего текстового поля и кнопки.
  3. В viewDidLoad установите для свойства кнопки isEnabled значение false и установите self в качестве textField.delegate.
  4. Реализуйте метод textField:shouldChangeCharactersInRange:replacementString:. Этот метод будет вызываться каждый раз, когда редактируется ваше текстовое поле. Там проверьте, преобразуется ли текущее текстовое поле в Int, вызвав toInt(), и включите/отключите вашу кнопку по своему усмотрению.

Вот код:

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        button.isEnabled = false
        textField.delegate = self
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        // Find out what the text field will be after adding the current edit
        let text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)

        if let intVal = text.toInt() {
            // Text field converted to an Int
            button.isEnabled = true
        } else {
            // Text field is not an Int
            button.isEnabled = false
        }

        // Return true so the text field will be changed
        return true
    }
}

Правка: в Swift 3 свойство enabled изменяется на isEnabled.

15
vacawama

Две вещи: 

  1. Укажите тип клавиатуры, чтобы отображалась только цифровая клавиатура. Итак, установите keyboardType в .numberPad. Однако этого недостаточно, чтобы пользователь не мог ввести недопустимые символы в текстовое поле. Например, пользователь все еще может вставлять текст или переключать клавиатуру при использовании iPad. 

  2. Укажите делегат текстового поля и реализуйте shouldChangeCharactersInRange, который не будет принимать никаких символов, кроме цифр 0, хотя 9:

    class ViewController: UIViewController, UITextFieldDelegate {
    
        @IBOutlet weak var textField: UITextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // you can set the following two properties for the text field in Interface Builder, if you'd prefer
    
            textField.delegate = self
            textField.keyboardType = .numberPad
        }
    
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let invalidCharacters = CharacterSet(charactersIn: "0123456789").inverted
            return string.rangeOfCharacter(from: invalidCharacters) == nil
        }
    
        // or, alternatively:
        //
        // func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
        //     return string.range(of: "^\\d*$", options: .regularExpression) != nil
        // }
    
    }
    

Для воспроизведения Swift 2 см. Предыдущую редакцию этого ответа.

52
Rob

Swift 4: Как насчет простых guard и typecasting to Int, как показано ниже

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        guard let _ = Int(string) else {
            button.isEnabled = false
            return true
        }
            button.isEnabled = true
            return true
}
3
Naishta

Каждое текстовое поле имеет переменную keyboardType. Вы можете установить это в UIKeyboardType.NumbersAndPunctuation, чтобы показывать только цифры и при этом иметь ключ возврата (защитный интерфейс). Затем вы можете использовать NSScanner's scanInt(), чтобы проверить, является ли textField.text действительным целым числом.

1
mumush

Во-первых, вы должны унаследовать класс UITextViewDelegate с вашим собственным учебный класс

class ViewController: UIViewController, UITextViewDelegate {

2-й добавить IBOutlet

@IBOutlet weak var firstName: UITextField!

3-й, вы должны убедиться, что этот объект использует

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



      }
  }
1
akbar khan

Что касается принятия возврата и других управляющих символов, я использовал следующий метод:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if string.isEmpty { // This is for accept control characters
        return true
    }
    let numericRegEx = "[0-9]"
    let predicate = NSPredicate(format:"SELF MATCHES %@", numericRegEx)

    let newText = (textFieldCount.text as! NSString).replacingCharacters(in: range, with: string)

    return predicate.evaluate(with: string)
}

Если вы хотите, чтобы он также принимал числа с плавающей запятой, просто измените RegEx на 

let numericRegEx = "[.0-9]"

Если размер текста ограничен 10, измените последнюю строку следующим образом:

return predicate.evaluate(with: string) && newText.count < 10
0
Dilmurat Abduqayyum

Вы можете использовать NSScanner, чтобы сделать это, вот что может быть полезным при использовании этого, и дайте мне знать, если есть какие-либо проблемы

if( [[NSScanner scannerWithString:@"-123.4e5"] scanFloat:NULL] )
    NSLog( @"\"-123.4e5\" is numeric" );
else
    NSLog( @"\"-123.4e5\" is not numeric" );

if( [[NSScanner scannerWithString:@"Not a number"] scanFloat:NULL] )
    NSLog( @"\"Not a number\" is numeric" );
else
    NSLog( @"\"Not a number\" is not numeric" );

перейдите по ссылке http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Objective-C . Попробуйте в Swift имена классов и методов совпадают.

0
yashwanth77

Вот метод многократного использования для Какао, Swift 4.1

1- Создайте файл с классом NSTextFieldFormated ниже

2- В « Identity инспектор » измените « Класс CustomClass » поля, которое нужно отформатировать в NSTextFieldFormated  

3- В « Атрибут атрибутов » определите « Минимальное значение int », « Максимальное значение int » и « Длина int » поля для форматирования

4- Перетащите «Объект» (NSObject) из « Библиотеки объектов » в « Просмотр сцены контроллера » в списке объектов построителя интерфейса структуры (слева от области рисования интерфейса).

5- В ' Инспекторе идентичности ' установите ' Класс CustomClass ' в NSTextFieldFormated

6- Выберите поле для форматирования и в инспекторе соединений установите делегат поля для нового ' Форматированное текстовое поле ' объект в ' Просмотр сцены контроллера '.

Затем NSTextField теперь отформатирован .

class NSTextFieldFormated: NSTextField, NSControlTextEditingDelegate {

    private struct Digit {
        var minValue: Int?      // minimum
        var maxValue: Int?      // maximum
        var digitAmt: Int?      // minimumIntegerDigits
    }
    private var digit = Digit()

    //-Integer
    @IBInspectable var intMinValue: Int {
        get {
            guard let minVal = digit.minValue else { return Int.min }
            return minVal
        }
        set { digit.minValue = newValue ; setFormatter() }
    }
    @IBInspectable var intMaxValue: Int {
        get {
            guard let maxVal = digit.maxValue else { return Int.max }
            return maxVal
        }
        set { digit.maxValue = newValue ; setFormatter() }
    }
    @IBInspectable var intLenght: Int {
        get {
            guard let length = digit.digitAmt else { return -1 }
            return length
        }
        set { digit.digitAmt = newValue ; setFormatter() }
    }

    private func setFormatter() {
        let lformatter = IntegerFormatter()
        lformatter.minimum = intMinValue as NSNumber
        lformatter.maximum = intMaxValue as NSNumber
        if intLenght != -1 {
            lformatter.minimumIntegerDigits = intLenght
        }
        self.formatter = lformatter
    }

    class IntegerFormatter: NumberFormatter {
        override func isPartialStringValid(_ partialString: String, 
            newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, 
            errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {

            if partialString.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) != nil {
                NSSound.beep()
                return false
            }

            return Int(partialString) != nil
        }
    }

    override func controlTextDidChange(_ notification: Notification) {
        if let textField = notification.object as? NSTextFieldFormated {
            if let val = Int(textField.stringValue) {
                //print(">4")
                if val > textField.intMaxValue {
                    textField.stringValue = String(textField.intMaxValue)
                }
            }
        }
    }
}
0
Luc-Olivier