簡體   English   中英

使用secureTextEntry為UITextField選擇鍵盤語言

[英]Selecting language of the keyboard for UITextField with secureTextEntry

我遇到了更改密碼字段語言的問題。 在我的應用程序中,我需要輸入希伯來語中的登錄名/密碼,而不管當前的語言環境。 當我嘗試輸入登錄時,它就可以了,我可以將鍵盤更改為希伯來語並輸入登錄名。 但是當我嘗試在安全的textField中輸入密碼時,鍵盤出現時沒有選擇語言按鈕,所以我只能輸入英文字母。

問題是登錄/密碼可以是英文或希伯來文。

如何將選擇語言按鈕放入安全的textField?

沒有找到解決方案。 不得不制作這個片段:

-(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:@"*"];
}
}

遺憾的是,此處發布的解決方案不適用於具有復合字符的語言(如韓語)。

韓語(Hangul)等語言具有復合字符,每個字母由多個符號組成。 例如,'ㅁ','ㅏ'和'ㄴ'都是單獨的字符,但組合后,它變為'만',被視為單個字母。

這是適用於所有語言的解決方案。

將UILabel放在UITextField的頂部。 將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項目以供參考。

優化@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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM