Существует большая дискуссия об этом, но я думаю, что все это сводится к персональному вкусу, точно так же, как использование 'этого' ключевого слова почти везде.
я лично предпочитаю explictly переменные определенного типа, но когда вложенные вещи универсальных наборов использования могут стать большим количеством читаемого использования переменной с неявно определенным типом. Посмотрите на:
Dictionary> myDictionary = new Dictionary>();
по сравнению с:
var myDictionary = new Dictionary>();
РЕДАКТИРОВАНИЕ: это ТАК тема затрагивает ту же тему с некоторыми хорошими ответами: , Что использовать: var или тип имени объекта?
EDIT2: Работая много с асинхронным в наше время, я нахожу, что использование explicity переменные определенного типа может иногда предотвращать противные ошибки. Рассмотрите этот глупый пример, где Вы хотели бы возвратить идентификатор пользователя. Также полагайте что GetUserAsync
возвраты Task
. При использовании переменных с неявно определенным типом Вы закончили бы тем, что использовали что-то вроде этого:
public long GetUserId()
{
var user = GetUserAsync();
return user.Id;
}
Это компилирует, но это неправильно. 'пользователь' на самом деле Task
. И это компилирует, как Task
также имеет Id
свойство. В этом случае можно было бы случайно возвратить идентификатор Задачи вместо Пользователя.
public long GetUserId()
{
User user = GetUserAsync();
return user.Id;
}
Вышеупомянутое не компилирует, поскольку компилятор будет жаловаться, что Вы не можете бросить Задачу Пользователю. При добавлении await
ключевое слово, конечно, решает это.
я на самом деле имел, это происходит со мной однажды:-)
Хорошо, я решил это сам. Скрытое текстовое поле было подходящим вариантом. Несмотря на то, что он скрыт, вы все равно можете сделать его первым респондентом, и клавиатура появится.
Итак, чтобы подвести итог:
In viewDidLoad:
[hidden becomeFirstResponder];
А затем я слушаю событие «Редактирование изменений» и обновляю четыре видимых поля UITextField по одному символу каждый. Примерно так:
- (IBAction)textChanged:(UITextField*)hiddenField
{
NSString *hiddenText = hiddenField.text;
[self setOneTextField:pin1 toString:hiddenText atIndex:0];
[self setOneTextField:pin2 toString:hiddenText atIndex:1];
[self setOneTextField:pin3 toString:hiddenText atIndex:2];
[self setOneTextField:pin4 toString:hiddenText atIndex:3];
}
- (void)setOneTextField:(UITextField*)textField toString:(NSString*)string atIndex:(NSInteger)index
{
if ([string length] > index)
textField.text = [string substringWithRange:NSMakeRange(index, 1)];
else
textField.text = @"";
}
Чтобы ограничить количество символов в скрытом UITextField четырьмя символами, я реализую метод делегата "shouldChangeCharactersInRange":
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
bool okToEdit = YES;
if (range.location > 3)
{
okToEdit = NO;
} else if (range.location == 3) {
[self performSelector:@selector(sendPinCodeNotification) withObject:nil afterDelay:0.0];
}
return okToEdit;
}
- (void)sendPinCodeNotification
{
[[NSNotificationCenter defaultCenter] postNotificationName:PINCODE_NOTIFICATION object:[NSString stringWithFormat:@"%@%@%@%@", pin1.text, pin2.text, pin3.text, pin4.text]];
}
И, как вы можете видеть, я отправляю уведомление, когда вводится четвертая цифра.
Что вам нужно сделать, так это подключить метод каждого из четырех событий UITextField "ValueChanged" и в этом методе проверить, равна ли длина текста отправителя 0.
Вы можете подключите событие ValueChanged для четырех полей UIText к тому же методу и включите тег, как вы это делали выше. Следующий код поможет решить эту проблему.
-(IBAction) pinChanged: (id)sender {
UITextField *currentField = (UITextField*) sender;
// if the field thqt has just been changed is blank
if ([currentField.text length] == 0) {
// switch on the fields tag, and go to the previous field
switch (currentField.tag) {
case 1:
// in first field already, stay here!
break;
case 2:
// go back to previous field
[pin1 becomeFirstResponder];
break;
case 3:
// go back to previous field
[pin2 becomeFirstResponder];
break;
case 4:
// go back to previous field
[pin3 becomeFirstResponder];
break;
default:
break;
}
}
}