Вот один из способов сделать это. Для эффективности мы построим dict
с первым значением в качестве ключа. Мы сохраняем значения в том порядке, в котором они отображаются (и кортежи в их первоначальном порядке, если вы используете Python> = 3.7 - в противном случае вам придется использовать collections.OrderedDict
)
def join_by_first(sequences):
out = {}
for seq in sequences:
try:
out[seq[0]].extend(seq[1:])
except KeyError:
out[seq[0]] = list(seq)
return [tuple(values) for values in out.values()]
join_by_first([('a', 'b'), ('a', 'c'),('d','f')])
# [('a', 'b', 'c'), ('d', 'f')]
Вот грубый план нападения, которое я использовал бы, если бы я должен был записать это теперь. Прием будет вводить в скрытый UITextField и обновлять UILabel с отформатированным значением как пользовательские типы.
На каждом нажатии клавиши будет обновлена маркировка, таким образом, пользователь будет чувствовать, как будто она редактирует отформатированное значение, когда она действительно редактирует скрытое текстовое поле. Как подлый!
Ну, это немного поздно, но я решил, что все равно попробую. Вероятно, это скорее обходной путь и может быть беспорядочный код, но у меня это сработало. Я соединил метку и скрытое текстовое поле в IB, и я написал этот код с помощью делегата UITextFieldDelegate.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == fineHiddenTextField) {
NSString *fineText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([fineText length] == 0) {
NSString *emptyFine = @"0.00";
float fineValue = [emptyFine floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
} else if ([fineText length] == 1) {
NSString *firstDec = [NSString stringWithFormat:@"0.0%@", fineText];
float fineValue = [firstDec floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
} else if ([fineText length] == 2) {
NSString *secondDec = [NSString stringWithFormat:@"0.%@", fineText];
float fineValue = [secondDec floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
} else {
int decimalPlace = [fineText length] - 2;
NSString *fineDollarAmt = [fineText substringToIndex:decimalPlace];
NSString *fineCentsAmt = [fineText substringFromIndex:decimalPlace];
NSString *finalFineValue = [NSString stringWithFormat:@"%@.%@", fineDollarAmt, fineCentsAmt];
float fineValue = [finalFineValue floatValue];
fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
}
//fineEntryLabel.text = [NSString stringWithFormat:@"%.2f", fineValue];
return YES;
}
}
Не совсем лучший, но он действительно выполнил свою работу. Первоначальный оператор if был предназначен только для того, чтобы убедиться, что это происходит только для этого одного конкретного текстового поля (поскольку на одной странице их несколько). Этот код был предназначен для ввода денег (сумма уплаченного штрафа), и я хотел он должен быть простым и легким в использовании. Просто установите этикетку так, чтобы она была выровнена по правому краю, и так и должно быть.
Я немного зациклен на кофе, но я отвечу на любые ваши вопросы. :)
Вот мое решение!
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
float valorUnit = [textField.text floatValue];
if( string.length > 0)
{
float incremento = [string floatValue];
valorUnit = valorUnit * 10.f + (incremento/100.f);
NSString* strVal = [NSString stringWithFormat:@"%f", valorUnit];
if (valorUnit > 0.f && valorUnit < 10.f) {
textField.text = [strVal substringToIndex:3];
}
else if (valorUnit < 100.f && valorUnit >= 10.f)
{
textField.text = [strVal substringToIndex:4];
}
else if (valorUnit >=100.f && valorUnit <1000.f)
{
textField.text = [strVal substringToIndex:5];
}
else {
return NO;
}
}
else {
valorUnit = (valorUnit/10.f);
NSString* strVal = [NSString stringWithFormat:@"%f", valorUnit];
if (valorUnit > 0.f && valorUnit < 10.f) {
textField.text = [strVal substringToIndex:5];
}
else if (valorUnit < 100.f && valorUnit >= 10.f)
{
textField.text = [strVal substringToIndex:6];
}
else if (valorUnit >=100.f && valorUnit <1000.f)
{
textField.text = [strVal substringToIndex:7];
}
else {
return NO;
}
}
return YES;
}
Что ж, думаю, так лучше:
- (void)viewWillDisappear:(BOOL)animated{ [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; }
-(void)viewDidAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged:) name:UITextFieldTextDidChangeNotification object:nil];
}
-(void)textDidChanged:(NSNotification *)notification{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
UITextField * textField= [notification object];
NSString * sinPesos= [textField.text stringByReplacingOccurrencesOfString:@"$" withString:@""];
NSString * sinPuntos= [sinPesos stringByReplacingOccurrencesOfString:@"." withString:@""];
float monto = [sinPuntos floatValue];
monto= monto/100;
NSString * cardText= [[self montoFormatter] stringFromNumber:[NSNumber numberWithDouble:monto]];
textField.text = ([cardText isEqualToString: @"0"] ? @"":cardText);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChanged:) name:UITextFieldTextDidChangeNotification object:nil];
}
-(NSNumberFormatter *)montoFormatter{
NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
return [numberFormatter autorelease];
}
Попробуйте :)
Мое решение:
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
// Clear all characters that are not numbers
// (like currency symbols or dividers)
NSString *cleanCentString = [[textField.text
componentsSeparatedByCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
componentsJoinedByString:@""];
// Parse final integer value
NSInteger centAmount = cleanCentString.integerValue;
// Check the user input
if (string.length > 0)
{
// Digit added
centAmount = centAmount * 10 + string.integerValue;
}
else
{
// Digit deleted
centAmount = centAmount / 10;
}
// Update call amount value
[_amount release];
_amount = [[NSNumber alloc] initWithFloat:(float)centAmount / 100.0f];
// Write amount with currency symbols to the textfield
NSNumberFormatter *_currencyFormatter = [[NSNumberFormatter alloc] init];
[_currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[_currencyFormatter setCurrencyCode:@"USD"];
[_currencyFormatter setNegativeFormat:@"-¤#,##0.00"];
textField.text = [_currencyFormatter stringFromNumber:_amount];
[_currencyFormatter release]
// Since we already wrote our changes to the textfield
// we don't want to change the textfield again
return NO;
}