В swift я пытаюсь создать текстовое поле, которое позволит включать кнопку, но только тогда, когда текстовое поле содержит целое число. Как я могу это сделать?
Как я могу объявить, что текстовое поле может содержать только целое число?
Ответ 1
- Сделайте ваш контроллер представления
UITextFieldDelegate
, добавивUITextFieldDelegate
в объявление класса. - Добавьте
IBOutlet
для вашего текстового поля и вашей кнопки. - В
viewDidLoad
установите для свойстваisEnabled
кнопки значениеfalse
и установите дляself
значениеtextField.delegate
. -
textField:shouldChangeCharactersInRange:replacementString:
метод. Этот метод будет вызываться каждый раз, когда редактируется ваше текстовое поле. Там проверьте, преобразуется ли текущее текстовое поле вInt
, вызвавInt(text)
и включите/отключите вашу кнопку по желанию.
Вот код:
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
textField.keyboardType = .numberPad
}
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 Int(text) != nil {
// 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
}
}
Ответ 2
Две вещи:
-
Укажите тип клавиатуры, чтобы отображалась только цифровая клавиатура. Итак, установите для типа
keyboardType
значение.numberPad
. Однако этого недостаточно, чтобы пользователь не мог ввести недопустимые символы в текстовое поле. Например, пользователь все еще может вставлять текст или переключать клавиатуру при использовании iPad. -
Укажите делегат текстового поля и реализуйте
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 см. Предыдущую редакцию этого ответа.
Ответ 3
Swift 4: как насчет простого guard
и typecasting to Int
как 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
}
Ответ 4
Во-первых, вы должны унаследовать класс 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
}
}
Ответ 5
Каждое текстовое поле имеет keyboardType
. Вы можете установить для этого параметра значение UIKeyboardType.NumbersAndPunctuation
, чтобы показывать только цифры и по-прежнему иметь ключ возврата (защитный интерфейс). Затем вы можете использовать NSScanner
scanInt()
, чтобы проверить, является ли textField.text допустимым целым числом.
Ответ 6
Вы можете использовать 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. Попробуйте в быстром классе и имена методов одинаковы.
Ответ 7
Здесь многоразовый метод для Cocoa, Swift 4.1
1- Создайте файл с классом NSTextFieldFormated ниже
2- В " Инспекторе идентичности " измените " Класс CustomClass " поля, которое нужно отформатировать, на NSTextFieldFormated.
3- В " Инспекторе атрибутов " определите " int Min Value ", " int Max Value " и " int Length " поля для форматирования
4- Перетащите "Объект" (NSObject) из " Библиотеки объектов " в " Просмотр сцены контроллера " в списке объектов построителя интерфейса структуры (слева от области рисования интерфейса).
5- В " Инспекторе идентичности " установите для " CustomClass class " значение 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)
}
}
}
}
}
Ответ 8
Что касается принятия возврата и других управляющих символов, я использовал следующий метод:
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
Ответ 9
В SWIFT 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == mobileTF{
let allowingChars = "0123456789"
let numberOnly = NSCharacterSet.init(charactersIn: allowingChars).inverted
let validString = string.rangeOfCharacter(from: numberOnly) == nil
return validString
}
return true
}