你如何dynamic地格式化一个数字在UITextField条目中有逗号?
我想在用户input时将逗号dynamic添加到我的数字UITextField
条目中。
例如: 123,456
和123,45
,但不是这样123,45
或123,4567
。
在用户在Objective-C中input数字时,如何自动附加逗号?
编辑:我也想能够让用户input小数。
而不是在shouldChangeCharactersInRange:
自行插入逗号,您可以使用NSNumberFormatterDecimalStyle
来处理逗号格式。 即使它被称为“十进制”样式,它也会插入逗号来适当地将数字分组到千位数中。
注意:为了简化问题,我假设您只想让文本字段接受数字条目,并且还会添加逻辑来将用户的input限制为数字。
编辑:我已经更新的代码来处理小数也按照OP的请求。
要在每个字符条目中使用NSNumberFormatterDecimalStyle
的格式,请尝试将其添加到您的shouldChangeCharactersInRange:
delegate方法中:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (([string isEqualToString:@"0"] || [string isEqualToString:@""]) && [textField.text rangeOfString:@"."].location < range.location) { return YES; } // First check whether the replacement string's numeric... NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]; NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; bool isNumeric = [string isEqualToString:filtered]; // Then if the replacement string's numeric, or if it's // a backspace, or if it's a decimal point and the text // field doesn't already contain a decimal point, // reformat the new complete number using // NSNumberFormatterDecimalStyle if (isNumeric || [string isEqualToString:@""] || ([string isEqualToString:@"."] && [textField.text rangeOfString:@"."].location == NSNotFound)) { // Create the decimal style formatter NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; [formatter setMaximumFractionDigits:10]; // Combine the new text with the old; then remove any // commas from the textField before formatting NSString *combinedText = [textField.text stringByReplacingCharactersInRange:range withString:string]; NSString *numberWithoutCommas = [combinedText stringByReplacingOccurrencesOfString:@"," withString:@""]; NSNumber *number = [formatter numberFromString:numberWithoutCommas]; NSString *formattedString = [formatter stringFromNumber:number]; // If the last entry was a decimal or a zero after a decimal, // re-add it here because the formatter will naturally remove // it. if ([string isEqualToString:@"."] && range.location == textField.text.length) { formattedString = [formattedString stringByAppendingString:@"."]; } textField.text = formattedString; } // Return no, because either the replacement string is not // valid or it is and the textfield has already been updated // accordingly return NO; }
使用分组属性格式化数字,如下所示。
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setGroupingSeparator:@","]; [numberFormatter setGroupingSize:3]; [numberFormatter setDecimalSeparator:@"."]; [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; [numberFormatter setMaximumFractionDigits:3]; [numberFormatter setMinimumFractionDigits:3];
上面代码的输出是
1,234,567.850
这里是Swift 3中的一个版本。我用它来整数,我没有用十进制数来检查。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // Uses the number format corresponding to your Locale let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.locale = Locale.current formatter.maximumFractionDigits = 0 // Uses the grouping separator corresponding to your Locale // eg "," in the US, a space in France, and so on if let groupingSeparator = formatter.groupingSeparator { if string == groupingSeparator { return true } if let textWithoutGroupingSeparator = textField.text?.replacingOccurrences(of: groupingSeparator, with: "") { var totalTextWithoutGroupingSeparators = textWithoutGroupingSeparator + string if string == "" { // pressed Backspace key totalTextWithoutGroupingSeparators.characters.removeLast() } if let numberWithoutGroupingSeparator = formatter.number(from: totalTextWithoutGroupingSeparators), let formattedText = formatter.string(from: numberWithoutGroupingSeparator) { textField.text = formattedText return false } } } return true }
这种方法的一大优点是它使用当前语言环境(区域)中定义的分组分隔符,因为不是每个人都使用逗号作为分组分隔符。
使用0,退格,但是,我再次没有用小数testing它。 如果你使用小数来处理,你可以自由地增强这个代码。
例子:
- input:“2” – >“2”
- input:“3” – >“23”
- input:“6” – >“236”
- input:“7” – >“2,367”
- input:“0”3次 – >“2,367,000”
- 退格 – >“236,700”
也从0开始工作:
- input:“0” – >“0”
- input:“2” – >“2”
使用UITextFieldDelegate方法:(您的视图控制器需要是文本字段的委托)
-(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
当一个字符被添加到textField时,它会调用这个方法。 然后,您可以在任何地方插入逗号。
注意:人们可以将文本粘贴到文本框中,删除值,移动光标等,这样您就有很多testing需要考虑。
这里有很多类似的问题,例如, 如何在我的UITextField中dynamic地添加逗号和小数?
在逗号分隔的UITextfield自动build议
等等
有风的请记住,逗号应该得到添加到号码本身,而不是像用户必须input它们。
第一
// Add a "textFieldDidChange" notification method to the text field control. [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
你必须改变自己改变文本。 而将添加逗号的代码是
-(void) textFieldDidChange { NSNumberFormatter *formatter = [NSNumberFormatter new]; [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; // this line is important! NSString *formatted = [formatter stringFromNumber:[NSNumber numberWithInteger:2000000]]; NSLog(@"the Formatted String is %@",formatted); textField.text = formatted; }
编辑见林赛斯科特的答案更新,正确的版本。
这是基于Lindsey Scott之前的回答,但更新为小数点后input的0:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField == _questionPoolNameTextField) { return YES; } //For 0's after the decimal point: if ([string isEqualToString:@"0"] && (0 <= (int)[textField.text rangeOfString:@"."].location)) { if ([textField.text rangeOfString:@"."].location < range.location) { return YES; } } // First check whether the replacement string's numeric... NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet]; NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; bool isNumeric = [string isEqualToString:filtered]; // Then if the replacement string's numeric, or if it's // a backspace, or if it's a decimal point and the text // field doesn't already contain a decimal point, // reformat the new complete number using // NSNumberFormatterDecimalStyle if (isNumeric || [string isEqualToString:@""] || ([string isEqualToString:@"."] && [textField.text rangeOfString:@"."].location == NSNotFound)) { NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setGroupingSeparator:@","]; [numberFormatter setGroupingSize:3]; [numberFormatter setDecimalSeparator:@"."]; [numberFormatter setMaximumFractionDigits:20]; [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; // Combine the new text with the old; then remove any // commas from the textField before formatting NSString *combinedText = [textField.text stringByReplacingCharactersInRange:range withString:string]; NSString *numberWithoutCommas = [combinedText stringByReplacingOccurrencesOfString:@"," withString:@""]; NSNumber *number = [numberFormatter numberFromString:numberWithoutCommas]; NSString *formattedString = [numberFormatter stringFromNumber:number]; // If the last entry was a decimal at the end of the // re-add it here because the formatter will naturally // remove it. if ([string isEqualToString:@"."] && range.location == textField.text.length) { formattedString = [formattedString stringByAppendingString:@"."]; } textField.text = formattedString; } // Return no, because either the replacement string is not // valid or it is and the textfield has already been updated // accordingly return NO; }
对于Lyndsey Scott的 Swift 3.0版的回答 :
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if ((string == "0" || string == "") && (textField.text! as NSString).range(of: ".").location < range.location) { return true } // First check whether the replacement string's numeric... let cs = NSCharacterSet(charactersIn: "0123456789.").inverted let filtered = string.components(separatedBy: cs) let component = filtered.joined(separator: "") let isNumeric = string == component // Then if the replacement string's numeric, or if it's // a backspace, or if it's a decimal point and the text // field doesn't already contain a decimal point, // reformat the new complete number using if isNumeric { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.maximumFractionDigits = 8 // Combine the new text with the old; then remove any // commas from the textField before formatting let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string) let numberWithOutCommas = newString.replacingOccurrences(of: ",", with: "") let number = formatter.number(from: numberWithOutCommas) if number != nil { var formattedString = formatter.string(from: number!) // If the last entry was a decimal or a zero after a decimal, // re-add it here because the formatter will naturally remove // it. if string == "." && range.location == textField.text?.length { formattedString = formattedString?.appending(".") } textField.text = formattedString } else { textField.text = nil } } return false }
- 在UICollectionView中创build慢速滚动到indexPath
- UITertController与UITextfield不显示标题和消息
- 如何在标签视图控制器故事板应用程序中添加更多选项卡?
- 从零到英雄:ImmobilienScout24 II上本地应用程序开发的故事
- 来自NSAttributedString的HTML
- 在I-pod / I-phone设备上无法点击覆盖pipe图像的图像
- 在iOS文档中使用rfc3339dateFormatter作为示例之后,dateFromString返回nil
- UIStackView:垂直轴肖像,水平轴风景
- 在iPhone上将整个pdf页面parsing为NSString