【问题标题】:Selecting language of the keyboard for UITextField with secureTextEntry使用 secureTextEntry 为 UITextField 选择键盘语言
【发布时间】:2011-07-26 10:44:23
【问题描述】:

我遇到了更改密码字段语言的问题。在我的应用程序中,我需要在不关心当前语言环境的情况下以希伯来语输入登录名/密码。当我尝试输入登录时,就可以了,我可以将键盘更改为希伯来语并输入登录。但是当我尝试在受保护的文本字段中输入密码时,出现的键盘没有选择语言按钮,所以我只能输入英文字母。

问题是登录名/密码可以是英语或希伯来语。

如何将选择语言按钮放到受保护的文本字段中?

【问题讨论】:

    标签: ios localization uitextfield


    【解决方案1】:

    没有找到解决办法。不得不做这个sn-p:

    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
    textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string];
    
    NSString *pass = password;
    pass = [pass stringByReplacingCharactersInRange:range withString:string];
    
    [password release];
    password = nil;
    
    password = [[NSString stringWithString:pass] retain];
    
    [self hideTextInTextFieldExceptOne:string];
    
    [self performSelector:@selector(hideTextInTextField) withObject:self afterDelay:1.0];
    
    return NO;
    }
    
    - (void)hideTextInTextFieldExceptOne:(NSString *)string
    {    
    int lenght = [passwordTextField.text length];
    
    for (int i = 0; i < lenght-1; i++)
    {
        NSRange range = NSMakeRange(i, 1);
        passwordTextField.text = [passwordTextField.text stringByReplacingCharactersInRange:range withString:@"*"];
    }
    }
    
    - (void)hideTextInTextField
    {
    NSUInteger lenght = [passwordTextField.text length];
    passwordTextField.text = @"";
    
    for (int i = 0; i < lenght; i++)
    {
        passwordTextField.text = [passwordTextField.text stringByAppendingString:@"*"];
    }
    }
    

    【讨论】:

    • 此解决方案适用,但不适用于具有韩语等复合字符的韩语(其中一个字母由多个字符组合而成)。请参阅我的适用于所有语言的解决方案。
    【解决方案2】:

    很遗憾,此处发布的解决方案不适用于具有复合字符的语言(如韩语)。

    像韩语(Hangul)这样的语言有一个复合字符,其中每个字母由多个符号组成。比如‘ㅁ’、‘ㅏ’和‘ㄴ’都是单独的字符,但是组合起来就变成了‘만’,被当作一个字母来处理。

    这是适用于所有语言的解决方案。

    在 UITextField 上放置一个 UILabel。将 UILabel 的框架设置为比 UITextField 略小,使其位于 UITextField 内,但仍会遮挡 UITextField 的文本。 textField: shouldChangeCharactersInRange:withReplacementString 在文本完成之前被调用。这意味着我们需要自己完成文本。这对于像韩语这样的复合字符语言更难做到。相反,注册 UITextFieldTextDidChangeNotification,它将在新文本出现在 UITextField 上后调用。

    @interface MKSecureTextField()<UITextFieldDelegate>
    @property (nonatomic, strong) UITextField* textField;
    @property (nonatomic, strong) UILabel* hideLabel;
    @property (nonatomic, strong) NSTimer* hideTimer;
    @property (nonatomic, strong) NSTimer* blinkTimer;
    @end
    
    @implementation MKSecureTextField
    
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self)
        {
            self.textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
            _textField.userInteractionEnabled = YES;
            _textField.borderStyle = UITextBorderStyleRoundedRect;
            _textField.font = [UIFont systemFontOfSize:14];
            _textField.placeholder = @"enter text";
            _textField.autocorrectionType = UITextAutocorrectionTypeNo;
            _textField.keyboardType = UIKeyboardTypeDefault;
            _textField.returnKeyType = UIReturnKeyDone;
            _textField.clearButtonMode = UITextFieldViewModeWhileEditing;
            _textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
            _textField.delegate = self;
    
            self.hideLabel = [[UILabel alloc] initWithFrame:CGRectMake(6, 5, frame.size.width-10, frame.size.height-12)];
            _hideLabel.backgroundColor = [UIColor whiteColor];
    
    
            [self addSubview:_textField];
            [self addSubview:_hideLabel];
    
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
    
        }
        return self;
    }
    

    当收到 UITextFieldTextDidChangeNotification 时,隐藏除最后一个字符之外的所有字符。隐藏文本将以编程方式在 UILabel 上设置。此外,安排一个将隐藏最后一个字符的计时器。如果键入更多文本,则此计时器无效。

    - (void)textFieldDidChange:(NSNotification*)notification
    {
        UITextField* textField = notification.object;
        if (textField == _textField)
        {
            NSString* text = textField.text;
    
    
            [self hideExceptLastCharacter:text];
    
            [self.hideTimer invalidate];
            self.hideTimer = [NSTimer scheduledTimerWithTimeInterval:1
                                                              target:self
                                                                  selector:@selector(hideLastCharacter)
                                                        userInfo:nil
                                                         repeats:NO];
    
    
        }
    }
    

    UILabel 没有闪烁的光标。所以我们通过在'|'之间交替来模拟它和一个空间。闪烁的光标在编辑开始时放置,在编辑结束时移除。

    - (void)textFieldDidBeginEditing:(UITextField *)textField
    {
        if (_hideLabel.text == nil)
        {
            _hideLabel.text =  @"|";
        }
        else
        {
            _hideLabel.text =  [_hideLabel.text stringByAppendingString:@"|"];
        }
    
        self.blinkTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(blinkCursor) userInfo:nil repeats:YES];
    }
    
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {
        NSRange range;
    
        range.location = _hideLabel.text.length - 1;
        range.length = 1;
    
        _hideLabel.text = [_hideLabel.text stringByReplacingCharactersInRange:range withString:@""];
    
        [_blinkTimer invalidate];
    }
    
    - (void)blinkCursor
    {
        if (_hideLabel.text.length > 0)
        {
            static BOOL visible = YES;
    
            NSRange range;
            range.location = _hideLabel.text.length - 1;
            range.length = 1;
    
            if (visible)
            {
                _hideLabel.text = [_hideLabel.text stringByReplacingCharactersInRange:range withString:@" "];
            }
            else
            {
                _hideLabel.text = [_hideLabel.text stringByReplacingCharactersInRange:range withString:@"|"];
            }
            visible = !visible;
        }
    }
    

    除了最后一个字符之外的字符被隐藏。这是在 UILabel 上设置的。 UITextField 保持不变。

    - (void)hideExceptLastCharacter:(NSString*)string
    {
        int length = [_textField.text length];
    
        NSString* s = @"";
        for (int i = 0; i < length-1; i++)
        {
            s = [s stringByAppendingString:@"●"];
        }
    
        if (_textField.text.length > 0)
        {
            _hideLabel.text = [s stringByAppendingString:[_textField.text substringFromIndex:_textField.text.length-1]];
            _hideLabel.text = [_hideLabel.text stringByAppendingString:@"|"];
        }
        else
        {
            _hideLabel.text = @"|";
        }
    }
    
    - (void)hideLastCharacter
    {
        if (_hideLabel.text.length > 1)
        {
            NSRange range;
            range.location = [_hideLabel.text length]-2;
            range.length = 1;
    
            _hideLabel.text = [_hideLabel.text stringByReplacingCharactersInRange:range withString:@"●"];
        }
    }
    
    - (void)dealloc
    {
        [_hideTimer invalidate];
        [_blinkTimer invalidate];
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    @end
    

    请参阅此Github project 以供参考。

    【讨论】:

      【解决方案3】:

      优化@lonlywolf 答案以获得更好的性能代码: 仅优化了两个循环的方法,当输入超过 30 个符号时会减慢程序速度

      - (void)hideTextInTextFieldExceptOne:(NSString *)string
      {
          int lenght = [passwordTextField.text length];
          if (lenght -1 > 0) {
              NSString *resultString = @"";
              for (int i = 0; i < lenght-1; i++)
              {
                  resultString = [resultString stringByAppendingFormat:@"*"];
              }
              NSRange range = NSMakeRange(0, lenght - 1);
              passwordTextField.text = [fieldPassword.text stringByReplacingCharactersInRange:range withString:resultString];
          }
      }
      
      - (void)hideTextInTextField
      {
          int lenght = [passwordTextField.text length];
          if (lenght > 0) {
              NSString *resultString = @"";
              for (int i = 0; i < lenght; i++)
              {
                  resultString = [resultString stringByAppendingFormat:@"*"];
              }
              passwordTextField.text = resultString;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-21
        • 1970-01-01
        • 2013-02-11
        • 2015-05-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多