스위프트에서 UITextField가 숫자만 가져가도록 제한하는 방법은?
사용자가 숫자 값만 입력하도록 합니다.UITextField
수 아이패드에서는 로도 바꿀수 . 아이폰에서는 숫자 키보드를 보여줄 수 있지만 아이패드에서는 어떤 키보드로도 바꿀 수 있습니다.
사용자가 숫자 값만 입력하도록 제한하는 방법이 있습니까?UITextField
?
참고: 이 질문은 오래된 질문으로 답이 많습니다.게시된 답변의 3분의 1 이상이 틀렸습니다.심지어 높은 지지를 받은 몇몇 답변들도 틀렸습니다.이 질문을 아직 보여주지 않은 방식으로 해결할 수 있는 매우 개선된 방법을 찾지 않는 한 새로운 답변을 게시하지 마십시오.당신의 대답이 모든 상황에서 효과가 있는지 확인하세요.그것은 아이폰과 아이패드 모두에 효과가 있어야 합니다.사용자가 텍스트 필드에 텍스트를 붙여넣을 때 작동해야 합니다.사용자가 외장 키보드를 가지고 있는 경우에는 반드시 작동해야 합니다.텍스트를 입력하거나 붙여넣기 전에 사용자가 텍스트 필드의 텍스트 선택을 변경하는 경우 이 옵션이 작동해야 합니다.십진 숫자(사용자 로케일에 적합한 십진 구분자 하나)를 적절하게 지원해야 합니다.
swift 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)
}
여기 제 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
}
이것은 단지 조금 더 엄격할 뿐입니다.소수점도 없습니다.
도움이 되길 바랍니다 :)
추신: 저는 당신이 대표님을 돌본 줄 알았습니다.
업데이트: 스위프트 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
}
In swift 4.1 및 Xcode 9.4.1
클래스에 UITTextFieldDelegate 추가
class YourViewController: UIViewController, UITextFieldDelegate
그런 다음 보기 DidLoad()에 이 코드를 작성합니다.
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
}
아이폰
이러한 값을 가져오는 UITTextField에서는 텍스트 필드 내부를 터치할 때 나타날 키보드 종류를 지정할 수 있습니다.
예를 들면 숫자로만 된 키보드
이 스크린샷처럼:
아이패드
iPad는 숫자 키보드를 지원하지 않으므로 iPad를 지원하지 않거나, 게시물 제출 필드의 유효성을 확인하거나, iPad에서 실행되는 동안 동일한 동작을 만들기 위해 여기에 있는 다른 제안 사항 중 하나를 따르는 것이 좋습니다.
스위프트 2.0
uitext 필드에 숫자와 "." 10진수를 하나만 허용하는 경우.
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
}
}
}
Swift 3에서 점(.dot)이 하나인 텍스트 필드의 10진수 값 허용
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
}
}
}
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
해당 텍스트 필드의 속성입니다.
보기 컨트롤러를 다음과 같이 확장합니다.
class MyViewController: UIViewController, UITextFieldDelegate
보기 DidLoad 기능은 다음과 같이 텍스트 필드로 확장됩니다.
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
}
그러면 사용자가 10진수만 입력할 수 있습니다.
스위프트 4 + 숫자만 허용하고 구분자 하나만 허용합니다.
번호포맷 사용
스위프트 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
}
간단한 해결 방법은 다음과 같습니다. "변경된 편집" 이벤트를 컨트롤러의 이 메서드에 연결해야 합니다.
스위프트 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()
}
}
}
먼저 자신의 클래스와 함께 UITextFieldDelegate 클래스를 상속해야 합니다.
class ViewController: UIViewController, UITextFieldDelegate {
두 번째로 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
}
}
이러한 솔루션의 대부분은 효과가 있겠지만, 일부 지역화에서는 소수점이 ""이 아닌 ""으로 구분된다는 점에 유의해야 합니다.
이것을 하는 더 깔끔한 방법은
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
}
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
}
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, "."를 허용할 뿐만 아니라 "."를 허용할 수 있기 때문에 더 복잡합니다.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let numRange = string.rangeOfCharacterFromSet(NSCharacterSet.letterCharacterSet()) {
return false
} else {
return true
}
}
숫자와 소수점 연산자를 하나만 허용하려면 다음 솔루션을 사용할 수 있습니다.
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)
}
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
}
위의 코드는 swift 3에서 작동하고 있습니다.
NS 문자 집합. 10진수
또한 문자만 사용합니다.
NS 문자 집합.편지
그리고 대문자,소문자, 알파벳 숫자, 공백이 동일한 코드로 사용되거나 링크 참조
보다 깨끗한 해결책은 다음과 같습니다.
guard CharacterSet(charactersIn: "123456789").isSuperset(of: CharacterSet(charactersIn: string)) else {
return false
}
return true
소수점에 대해서는 추가하기만 하면 됩니다..
,123456789.
키보드 설정유형 속성 : - 번호 패드 텍스트 필드 위임자 코드 아래에 기록하십시오.
func textField(_ textField: UITextField, shouldChangeCharactersIn
range: NSRange, replacementString string: String) -> Bool {
if textField.text?.count == 0 && string == "0" {
return false
}
return string == string.filter("0123456789".contains)
}
숫자는 0부터 시작해서 숫자 +ve를 입력하면 안 됩니다.
//이 중 instead은 키보드를 숫자로 간단히 변경할 수 있습니다.
yourtextfield.keyboardType = UIKeyboardType.numberPad
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
}
답이 부족한 것처럼, 여기 제 것이 있습니다.소수점 구분자에 허용되는 모든 예는 현지화, 백스페이스 또는 복사/붙여넣기에서 결함이 있다고 생각합니다.
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
}
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
}
}
이 기능을 "제출" 또는 "저장" 방법으로 설정합니다.
다음은 제가 스위프트 3.0에서 사용한 코드로 H씨의 코드를 각색한 것입니다.차이점은 다음과 같습니다.
a) 스위프트 3.0에서 Delegate 함수 선언이 변경되었습니다.여기에 새 선언
b) NS 문자 집합 선언이 변경되었습니다.
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
}
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
}
}
}
소수 구분 기호 및/또는 음수를 허용하려면 이 코드를 사용할 수 있습니다.그러나 이 코드는 텍스트를 변경하는 동안 예: "34."(끝의 소수 구분자)를 허용합니다.따라서 textFieldShouldReturn 또는 textFieldShouldEndEditingdelegate 함수와 같은 몇 가지 코드 예제를 추가해야 합니다.
스위프트 4로 작성된 코드인데 스위프트 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 = ""
일부 문자 허용
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
이 버전은 "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
}
}
}
문자열 확장 메서드와 함께 ChangeCharactersInRange를 사용하여 입력 문자열이 숫자인지 확인할 수 있습니다.
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
}
완벽하게 간단한 솔루션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
}
언급URL : https://stackoverflow.com/questions/30973044/how-to-restrict-uitextfield-to-take-only-numbers-in-swift
'programing' 카테고리의 다른 글
데카르트 제품을 피하기 위해 SQL View 최적화 (0) | 2023.10.18 |
---|---|
sql distinct 또는 그룹화하여 올바른 순서를 가져옵니다. (0) | 2023.10.18 |
왜 음의 오류를 반환합니까?(예: 반환 -EIO) (0) | 2023.10.18 |
워드 프레스 쇼트 코드가 잘못된 위치에 있음 (0) | 2023.10.18 |
C/C++가 표준 ABI를 정의할 경우 "잃을" 수 있는 것은 무엇입니까? (0) | 2023.10.18 |