Как ограничить текстовую длину NSTextField и всегда сохранять ее верхним регистром?

Вот, пожалуйста! просто добавил отступ справа от имени и разделил метку и ввод в два разных элемента div:)

.name{
  float: left;
  padding-right: 4%;
}
<div class="name">
        <label for="First_Name">First Name:</label>
        <input name="first_name" id="First_Name" type="text" />
</div>
<div class="lastname">
        <label for="Name">Last Name:</label>
        <input name="last_name" id="Last_Name" type="text" /> 
</div>

25
задан Carlos Barbosa 5 May 2009 в 21:39
поделиться

4 ответа

I did as Graham Lee suggested and it works fine, here's the custom formatter code:

UPDATED: Added fix reported by Dave Gallagher. Thanks!

@interface CustomTextFieldFormatter : NSFormatter {
  int maxLength;
}
- (void)setMaximumLength:(int)len;
- (int)maximumLength;

@end

@implementation CustomTextFieldFormatter

- (id)init {

   if(self = [super init]){

      maxLength = INT_MAX;
   }

  return self;
}

- (void)setMaximumLength:(int)len {
  maxLength = len;
}

- (int)maximumLength {
  return maxLength;
}

- (NSString *)stringForObjectValue:(id)object {
  return (NSString *)object;
}

- (BOOL)getObjectValue:(id *)object forString:(NSString *)string errorDescription:(NSString **)error {
  *object = string;
  return YES;
}

- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
   proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
          originalString:(NSString *)origString
   originalSelectedRange:(NSRange)origSelRange
        errorDescription:(NSString **)error {
    if ([*partialStringPtr length] > maxLength) {
        return NO;
    }

    if (![*partialStringPtr isEqual:[*partialStringPtr uppercaseString]]) {
      *partialStringPtr = [*partialStringPtr uppercaseString];
      return NO;
    }

    return YES;
}

- (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes {
  return nil;
}

@end
46
ответ дан 28 November 2019 в 17:59
поделиться

Вы пытались подключить пользовательский подкласс NSFormatter ?

12
ответ дан 28 November 2019 в 17:59
поделиться

Лучше всего подойдет пользовательский NSFormatter, предложенный Грэмом Ли.

Простым клуджем было бы установить контроллер представления в качестве делегата текстового поля, а затем просто заблокировать любое редактирование, в котором используется не верхний регистр или делает длину более 4:

- (BOOL)textField:(UITextField *)textField
    shouldChangeCharactersInRange:(NSRange)range
    replacementString:(NSString *)string
{
    NSMutableString *newValue = [[textField.text mutableCopy] autorelease];
    [newValue replaceCharactersInRange:range withString:string];

    NSCharacterSet *nonUppercase =
        [[NSCharacterSet uppercaseLetterCharacterSet] invertedSet];
    if ([newValue length] > 4 ||
        [newValue rangeOfCharacterFromSet:nonUppercase].location !=
            NSNotFound)
    {
       return NO;
    }

    return YES;
}
-4
ответ дан 28 November 2019 в 17:59
поделиться

В приведенном выше примере, где я прокомментировал, это плохо:

// 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) Пользователь вставит в текстовое поле

2) TextField принимает строку символов

3) TextField применяет средство форматирования к «последнему» символу в строке длиной 25

4) Средство форматирования выполняет действия с «последним» символом из 25 -длина строки, остальные игнорируются

5) TextField будет содержать 25 символов, хотя и ограничено 10.

Это потому, что, как я полагаю, первый метод применяется только к «самому последнему символу». "введено в NSTextField. Второй метод, показанный выше, применяется ко «всем символам», набранным в NSTextField. Так что он невосприимчив к эксплойту "паста".

Я обнаружил это только сейчас, пытаясь взломать свое приложение, и не являюсь экспертом по NSFormatter, поэтому, пожалуйста, поправьте меня, если я ошибаюсь. И большое спасибо вам carlosb за размещение этого примера. Это ОЧЕНЬ помогло! :)

12
ответ дан 28 November 2019 в 17:59
поделиться