2014-09-16 1 views
1

У меня есть экран Client Details со многими UITextField. Мне нужно ограничить postcodeField максимум 7 символами и автоматически конвертировать в верхний регистр. У меня уже есть код, чтобы преобразовать текст в верхний регистр, но, кажется, я не могу что-нибудь еще с этим конкретным UITextField делать в Delegate методеУстановить максимальную длину UITextField и преобразовать в верхний регистр?

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 

Вот что я пробовал:

#define MAXLENGTH 7 
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    if (textField == self.postcodeField) { 
     self.postcodeField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; 
     return NO; 
    } 
    if (self.postcodeField.text.length >= MAXLENGTH && range.length == 0) 
    { 
     return NO; 
    } 
    return YES; 
} 

А:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    if (textField == self.postcodeField) { 
     self.postcodeField.text = [textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]; 
     return NO; 
    } 

    NSUInteger newLength = [textField.text length] + [string length] - range.length; 
    return (newLength > 7) ? NO : YES; 
} 

Этот код не работает. Я знаю, что существует множество потоков с различными решениями для установки максимальной длины, но я не могу найти решение, которое также поддерживает преобразование в верхнем регистре. Я совершенно новичок в iOS, поэтому прошу прощения, если это рассматривается как дубликат. Любая помощь высоко ценится!

ответ

0

я решил внедрить новый метод для достижения того, что я хочу. Мой метод UITextField delegate- (BOOL)textField: shouldChangeCharactersInRange: replacementString: становился очень грязным, так как к представлению добавлялось больше текстовых полей, все из которых делают разные вещи. Поэтому я создал подкласс для использования в нужном поле почтового индекса. Я не смог использовать размещенное решение в подклассе UITextField, так как плохо установить delegate для себя в этом подклассе (известная проблема с подклассом UITextField - см. this, this и this.). Новый код более эффективен, чем тот, который я принял ранее, и может быть широко адаптирован для выполнения многих задач.

Заголовочный файл:

PostcodeField.h 

@interface PostcodeField : UITextField 

- (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range; 

@end 

Реализация подкласса (еще одно требование было принимать только определенные символы, которые были легко реализованы):

PostcodeField.m 

#define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 
#define CHARACTER_LIMIT 8 

@implementation PostcodeField 
- (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range { 
    NSUInteger newLength = [self.text length] + [string length] - range.length; 
    // Check text meets character limit 
    if (newLength <= CHARACTER_LIMIT) { 
     // Convert characters to uppercase and return acceptable characters 
     NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet]; 
     NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; 
     [self setText:[self.text stringByReplacingCharactersInRange:range withString:[filtered uppercaseString]]]; 
    } 
    return NO; 
} 

Тогда я поставил delegate к self на требуемое текстовое поле в пределах ViewController:

self.postcodeField.delegate = self; 

И называют это delegate метод на ViewController:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    // Call PostcodeField subclass on Postcode textfield 
    if ([textField isKindOfClass:[PostcodeField class]]) { 
     return [(PostcodeField *)textField stringIsAcceptable:string inRange:range]; 
    } 
    return YES; 
} 

И, конечно, импортировать подкласс на ViewController:

#import "PostcodeField.h" 

Вы можете установить текстовое поле, чтобы использовать подкласс, перейдя в " Identity Inspector ", используя IB (Interface Builder) и установив Custom Class в ваш подкласс:

PostcodeField subclass using IB

Используя подклассы, ваш метод UITextField delegate может быть более чистым и более эффективным, а подкласс может быть вызван как можно большим количеством текстовых полей. Если на этом представлении имеется несколько текстовых полей, просто следуйте одному и тому же процессу и испытайте для каждого подкласса в методе UITextField delegate. Я надеюсь, что этот пост будет полезен для тех, кто хочет использовать подклассы на UITextFields.

2

Это угрюмо поможет ограничить до 7 символов.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 

    [textField setText:[textField.text uppercaseString]]; 
    NSUInteger newLength = [textField.text length] + [string length] - range.length; 
    return (newLength > 7) ? NO : YES; 
} 
+0

Я пробовал это, и он работает, но ограничивает все текстовые поля до 7 символов. Я не знаю, как реализовать его в моем методе вместе с кодом, который у меня уже есть (для преобразования текста в верхний регистр). Не могли бы вы рассказать о том, как это реализовано? Благодарю. – rosshump

+0

Не нужно добавлять его нигде. Просто добавьте делегата в свой TextField. Он будет вызываться автоматически. Пожалуйста, примите ответ, чтобы зрители, которые застряли в одной и той же проблеме, были легкими. –

+0

Извините, но я не совсем понимаю вас. Я добавил делегата в текстовое поле, и он автоматически вызван, но мне также нужен код для его преобразования в верхний регистр. Добавляя свой код к методу, символы больше не преобразуются в верхний регистр. Извините, если мне не хватает простого решения! – rosshump

1

На мой взгляд, лучше подход к вашей проблеме заключается в использовании NSNotificationCenter с UITextFieldTextDidChangeNotification

Затем вы можете добавить этот код в viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(maxLength:) 
              name:UITextFieldTextDidChangeNotification 
              object:self.postcodeField]; 

то, что вам нужно только добавить селекторный метод, например:

- (void) maxLength: (NSNotification*) notification 
{ 
    UITextField *notificationTextField = [notification object];  
    if (notificationTextField == self.postcodeField) 
    { 
     if (self.postcodeField.text.length >= MAXLENGTH) 
     { 
      // remove here the extra text 
     } 
    } 
} 
0

У меня есть ru п этот код и его работает нормально, поэтому попробовать его

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    if(textField==self.txtPostCodeField) 
    { 
     int limit = 100; 
     return !([textField.text length]>=limit && [string length] >= range.length); 
    } 
    return YES; 
} 
0

В Swift вы можете использовать код, указанный ниже.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool 
{ 
    if(range.length + range.location > countElements(textField.text)) 
    { 
     return false 
    } 
    textField.autocapitalizationType = UITextAutocapitalizationType.AllCharacters // Capitalize the all characters automatically 
    var newLength: Int = countElements(textField.text) + countElements(string) - range.length 
    return (newLength > 7) ? false : true 
} 
+0

Это не мешает пользователю нажать клавишу Shift, чтобы отключить капитализацию. Также, похоже, это не соблюдается всеми сторонними клавиатурами, такими как Swiftkey. – stone

 Смежные вопросы

  • Нет связанных вопросов^_^