如何使用Swift将UITextField限制为一个小数点?文本字段用于输入价格,因此我不能允许超过一个小数点。如果我使用的是Objective-C,我会使用这段代码:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSArray *sep = [newString componentsSeparatedByString:@"."];
if([sep count] >= 2)
{
NSString *sepStr=[NSString stringWithFormat:@"%@",[sep objectAtIndex:1]];
return !([sepStr length]>1);
}
return YES;
}
但是由于Swift使用范围的方式存在差异,我无法将此代码转换为Swift。第一行给出了一个错误NSRange is not convertible to Range<String.Index>
编辑:在我看到答案之前,我最终这样做了:
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
let tempRange = textField.text.rangeOfString(".", options: NSStringCompareOptions.LiteralSearch, range: nil, locale: nil)
if tempRange?.isEmpty == false && string == "." {
return false
}
return true
}
我在另一篇文章中发现了这一点。这个解决方案工作正常,但我不确定这是否是最好的方法,但它是一个简短而干净的方式。
答案 0 :(得分:4)
Alexey在我之前到达那里,但看到我已经实施了一个Swift版本来检查问题,这里是:
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
// I'm explicitly unwrapping newString here, as I want to use reverse() on it, and that
// apparently doesn't work with implicitly unwrapped Strings.
if let newString = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string) {
var decimalFound = false
var charactersAfterDecimal = 0
for ch in reverse(newString) {
if ch == "." {
decimalFound = true
break
}
charactersAfterDecimal++
}
if decimalFound && charactersAfterDecimal > 1 {
return false
}
}
return true;
}
请注意,第一行现在显式地将textField.text强制转换为NSString。这是因为stringByReplacingCharactersInRange的String版本采用Swift范围,而不是传入的NSRange。
我还使后来的代码更多Swiftian,删除了NSString操作。 (我不相信这是非常有效的,因为reverse(String)实际上可能会反转整个String而不是提供一个简单的后向迭代器,但它看起来是最常用的方式。)
答案 1 :(得分:1)
你在Swift的第一行看起来像:
var newString = NSString(string: textField.text).stringByReplacingCharactersInRange(range, withString: string)
答案 2 :(得分:0)
我建议使用NSNumberFormatter的decimalSeparator属性来拆分String。以下是仅使用NSNumberFormatter将输入限制为一个小数位的方法:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if string.isEmpty { // back key
return true
}
if let input = textField.text {
let numberFormatter = NSNumberFormatter()
let range = input.rangeOfString(numberFormatter.decimalSeparator)
if let r = range {
let endIndex = input.startIndex.advancedBy(input.startIndex.distanceTo(r.endIndex))
let decimals = input.substringFromIndex(endIndex)
return decimals.characters.count < 1
}
}
return true
}
答案 3 :(得分:0)
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (textField.text?.componentsSeparatedByString(".").count > 1 && string == ".")
{
return false
}
return string == "" || (string == "." || Float(string) != nil)
}
答案 4 :(得分:0)
尝试使用一个十进制条目: -
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if(string == "." ){
let countdots = textField.text!.componentsSeparatedByString(".").count - 1
if countdots > 0 && string == "."
{
return false
}
}
return true
}
答案 5 :(得分:0)
Swift 4&amp; Xcode 9.2
此解决方案只允许输入一个小数点,因此允许有效的双倍。
// Only allows one decimal point
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
let arrayOfString = newString.components(separatedBy: ".")
if arrayOfString.count > 2 {
return false
}
return true
}
答案 6 :(得分:0)
我希望它可以帮到你:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
let stringArr: [String] = newString.components(separatedBy: ".")
if stringArr.count < 2 || (stringArr.count == 2 && stringArr[1].count == 1){
return true
}
return false
}
答案 7 :(得分:0)
Swift 4,Xcode 9.2
这将删除最后输入的小数点:
let numberOfDecimalPoints = textField.text.components(separatedBy: ".").count - 1
if numberOfDecimalPoints > 1 {
textField.deleteBackward()
}
答案 8 :(得分:0)
我不确定性能,但这是迄今为止最简单的解决方案。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text {
// Allow only one dot character in the text field
if text.contains(".") && string == "." {
return false
}
}
}