在我的应用程序中,用户需要能够输入带小数点的数字值。 iPhone不提供专门用于此目的的键盘 - 只有数字键盘和带有数字和符号的键盘。输入带小数点的数值的最佳方法是什么?
有没有简单的方法来使用后者,并防止输入任何非数字输入而不必将正则表达式正则表达式?
谢谢!
在我的应用程序中,用户需要能够输入带小数点的数字值。 iPhone不提供专门用于此目的的键盘 - 只有数字键盘和带有数字和符号的键盘。输入带小数点的数值的最佳方法是什么?
有没有简单的方法来使用后者,并防止输入任何非数字输入而不必将正则表达式正则表达式?
谢谢!
更优雅的解决方案碰巧也是最简单的。
你并不需要一个小数点键
为什么?因为你可以简单地从用户的输入中推断出它。例如,在美国语言环境中,当您输入1.23美元时,首先输入1-2-3(按该顺序)。
通知我们如何根据用户的输入推断小数点分隔符。现在,如果用户想要输入$ 1.00,他们只需输入1-0-0。
为了让您的代码处理不同区域设置的货币,您需要获取货币的最大分数位数。这可以用下面的代码片段来完成:
NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
int currencyScale = [currencyFormatter maximumFractionDigits];
例如,日元有0的最大分数位数所以,随着日元输入打交道时,没有小数点分隔符,因此没有必要连担心分数金额。
这种方法的问题,您可以使用自定义的无键盘,正则表达式验证的头痛苹果提供的库存数字输入键盘等
根据具体的应用,提供一个滑块,用户可以选择一个位置可能是一个更好的选择在iphone上。然后根本不需要输入任何数字。
您可能想要为每个数字使用一个滑块(如Martin v。Löwis所建议的)或UIPickerView,并使用单独的滑轮。
我想做的完全一样的事情,除了货币而不是直接十进制值。
我最终创建了一个包含UITextField和UILabel的自定义视图。标签覆盖了文本字段,但文本字段仍然接收到触摸。我使用UITextFieldTextDidChange通知来观察文本字段中的更改(并且我使用NSNumberFormatter将结果数字转换为格式化的货币值)以更新标签。
要禁用允许用户重新定位插入点的放大镜,您需要使用自定义UITextField子类并覆盖touchesBegan:withEvent:并将其设置为不执行任何操作。
我的解决方案可能与您需要的不同,因为小数点总是固定的 - 我使用系统的货币设置来确定小数点后应该有多少数字。但是,数字小键盘上没有小数点。你不能在键盘上添加任何按钮(这是特别加重的,因为在键盘的左下角有一个空白按钮,这对于小数点来说是完美的!)所以我没有解决方案,不幸的是。
下面是一个例子为解决中接受的答案建议。这不处理其他货币或者任何东西 - 在我的情况下,我只需要对美元的支持,无论在什么区域/货币所以这是确定对我来说:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
double currentValue = [textField.text doubleValue];
//Replace line above with this
//double currentValue = [[textField text] substringFromIndex:1] doubleValue];
double cents = round(currentValue * 100.0f);
if ([string length]) {
for (size_t i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if (isnumber(c)) {
cents *= 10;
cents += c - '0';
}
}
} else {
// back Space
cents = floor(cents/10);
}
textField.text = [NSString stringWithFormat:@"%.2f", cents/100.0f];
//Add this line
//[textField setText:[NSString stringWithFormat:@"$%@",[textField text]]];
return NO;
}
的两轮和地板是很重要的一个),因为的浮点数表示有时会丢失.00001或其他值,b)格式字符串会舍去我们在退格部分删除的任何精度。
我建有小数点的自定义数字键盘视图控制器...检查出来:
http://sites.google.com/site/psychopupnet/iphone-sdk/tenkeypadcustom10-keypadwithdecimal
由于对iOS4.1的,有一个新的键盘类型UIKeyboardTypeNumberPad,但遗憾的是,由于但它似乎并未出现在界面生成器选择列表中。
下面介绍如何在货币不可知的情况下使用浮动,round()或ceil()。
在您的视图控制器,设置以下实例变量(关联@property声明,如果这是你的包):
@interface MyViewController : UIViewController <UITextFieldDelegate> {
@private
UITextField *firstResponder;
NSNumberFormatter *formatter;
NSInteger currencyScale;
NSString *enteredDigits;
}
@property (nonatomic, readwrite, assign) UITextField *firstResponder;
@property (nonatomic, readwrite, retain) NSNumberFormatter *formatter;
@property (nonatomic, readwrite, retain) NSString *enteredDigits;
@end
和您的viewDidLoad方法中应包含以下内容:
- (void)viewDidLoad {
[super viewDidLoad];
NSNumberFormatter *aFormatter = [[NSNumberFormatter alloc] init];
[aFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
currencyScale = -1 * [aFormatter maximumFractionDigits];
self.formatter = aFormatter;
[aFormatter release];
}
然后执行您的UITextFieldDelegate方法,如下所示:
#pragma mark -
#pragma mark UITextFieldDelegate methods
- (void)textFieldDidBeginEditing:(UITextField *)textField {
// Keep a pointer to the field, so we can resign it from a toolbar
self.firstResponder = textField;
self.enteredDigits = @"";
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([self.enteredDigits length] > 0) {
// Get the amount
NSDecimalNumber *result = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale];
NSLog(@"result: %@", result);
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Check the length of the string
if ([string length]) {
self.enteredDigits = [self.enteredDigits stringByAppendingFormat:@"%d", [string integerValue]];
} else {
// This is a backspace
NSUInteger len = [self.enteredDigits length];
if (len > 1) {
self.enteredDigits = [self.enteredDigits substringWithRange:NSMakeRange(0, len - 1)];
} else {
self.enteredDigits = @"";
}
}
NSDecimalNumber *decimal = nil;
if (![self.enteredDigits isEqualToString:@""]) {
decimal = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale];
} else {
decimal = [NSDecimalNumber zero];
}
// Replace the text with the localized decimal number
textField.text = [self.formatter stringFromNumber:decimal];
return NO;
}
只用磅和便士测试过,但它也应该与日元一起使用。如果您想为非货币目的设置小数位数,那么只需阅读NSNumberFormatter上的文档并设置您想要的格式/ maximumFractionDigits即可。
我认为应该指出,从iOS 4.1开始,您可以使用新的UIKeyboardTypeDecimalPad
。
所以,现在你只需要:
myTextField.keyboardType=UIKeyboardTypeDecimalPad;
迅速2实施迈克韦勒的帖子,也只有USD:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
guard let str = textField.text else {
textField.text = "0.00"
return false
}
let value = (str as NSString).doubleValue
var cents = round(value * 100)
if string.characters.count > 0 {
for c in string.characters {
if let num = Int(String(c)) {
cents *= 10
cents += Double(num)
}
}
}
else {
cents = floor(cents/10)
}
textField.text = NSString(format: "%.2f", cents/100) as String
return false
}
您可以使用STATextField并设置currencyRepresentation为YES其中:
确保不会输入一个以上的小数点,并且输入不超过两位数字t的小数点。
还有STAATMTextField它默认支持货币模式和 ATM文本输入:
提供的文本字段模仿ATM机输入行为。
只是为了确保 - 不要使用浮动货币! – Svante 2009-02-24 01:16:24
+1 - 使用NSDecimalNumber – shek 2009-02-25 04:40:56
我也写过关于这对任何人的博客贴子,有兴趣:http://blog.weareuproar.com/?p=11 – shek 2009-03-12 03:57:06