В приведенном выше примере, где я прокомментировал, это плохо:
// Don't use:
- (BOOL)isPartialStringValid:(NSString *)partialString
newEditingString:(NSString **)newString
errorDescription:(NSString **)error
{
if ((int)[partialString length] > maxLength)
{
*newString = nil;
return NO;
}
}
Используйте это (или что-то подобное) вместо:
// Good to use:
- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
originalString:(NSString *)origString
originalSelectedRange:(NSRange)origSelRange
errorDescription:(NSString **)error
{
int size = [*partialStringPtr length];
if ( size > maxLength )
{
return NO;
}
return YES;
}
Оба являются методами NSFormatter. У первого есть проблема. Допустим, вы ограничиваете ввод текста до 10 символов. Если вы вводите символы один за другим в NSTextField, это будет нормально работать и не позволит пользователям выходить за пределы 10 символов.
Однако, если пользователь вставит строку, скажем, 25 символов в текстовое поле, произойдет что-то вроде этого:
1) Пользователь вставит в TextField
2) TextField будет принимать строку символов
3) TextField применит форматер к «последнему» символу в строке длиной 25
4) Formatter выполняет работу с «последним» символом в строке длиной 25, игнорируя остальные
5) TextField будет содержать 25 символов, хотя он ограничен 10.
Это потому, что, я полагаю, первый метод применяется только к «самому последнему символу», введенному в NSTextField. Второй метод, показанный выше, применяется ко всем символам, введенным в NSTextField. Так что он невосприимчив к эксплойту "paste".
Я обнаружил это только сейчас, пытаясь сломать мое приложение, и я не эксперт по NSFormatter, поэтому, пожалуйста, исправьте меня, если я ошибаюсь. И большое спасибо вам carlosb за публикацию этого примера. Это помогло МНОГО! :)