设置UITextField的最大长度并转换为大写?

时间:2014-09-16 08:36:19

标签: ios objective-c uitextfield subclass uitextfielddelegate

我有一个Client Details屏幕,其中包含许多UITextField。我需要将postcodeField限制为最多7个字符并自动转换为大写。我已经有了将文本转换为大写的代码,但似乎我无法对UITextField方法中的特定Delegate执行任何其他操作

- (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很陌生,所以如果这被视为重复的帖子我很抱歉。非常感谢任何帮助!

5 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

在我看来,更好的解决方法是将NSNotificationCenterUITextFieldTextDidChangeNotification一起使用

然后,您可以将此代码添加到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
        }
    }
}

答案 2 :(得分:0)

我已运行此代码并且其工作正常,因此请尝试

 -(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;
}

答案 3 :(得分:0)

我决定实施一种新方法来实现我想要的。随着更多文本字段添加到视图中,我的UITextField delegate方法- (BOOL)textField: shouldChangeCharactersInRange: replacementString:变得非常混乱,所有这些都在做不同的事情。所以我创建了一个子类,用于所需的Postcode字段。我无法在UITextField的子类中使用已发布的解决方案,因为在该子类中将delegate设置为self是很糟糕的(UITextField子类化的已知问题 - 请参阅thisthisthis。)。新代码比我之前接受的答案更有效,并且可以广泛适应做很多事情。

标题文件:

PostcodeField.h

@interface PostcodeField : UITextField

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

@end

子类实现(另一个要求是只接受易于实现的指定字符):

PostcodeField.m

#define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#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设置为selfViewController所需的文本字段:

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"

您可以通过导航到&#34; Identity Inspector&#34;来设置文本字段以使用子类。使用IB(Interface Builder)并将Custom Class设置为您的子类:

PostcodeField subclass using IB

通过使用子类,您的UITextField delegate方法可以更干净,更高效,并且可以根据需要在尽可能多的文本字段上调用子类。如果该视图上有多个文本字段,则只需遵循相同的过程并测试UITextField delegate方法中的每个子类。我希望这篇文章对于想要在UITextFields上使用子类的人有所帮助。

答案 4 :(得分: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
}