web-dev-qa-db-ja.com

UITextField secureTextEntry-YESからNOまで機能しますが、YESに変更しても効果はありません

上記はすべてを言っています-UITextFieldをセキュリティで保護するように設定していますが、ユーザーにそれをセキュリティで保護しないようにするオプションを提供したいと考えています(プライベート領域にいる場合、ユーザーが入力した内容を確実に確認できます)。しかし、誤ってトグルを押して、セキュアモードに戻したいとしますか?それは機能しません。私はすべてを試しました-YESの代わりに-1を使用し、テキストを削除してから元に戻しました。私は他のアイデアに全く困っています。 [rdar:// 9781908に入った]

編集:この問題はiOS5で修正されたと思います。

27
David H

これは入力フォーカスの問題である必要があります。フォーカスされている場合、UITextFieldはON-> OFFのみを変更できます。
次のトリックを試して、OFF-> ONに切り替えます。

textField.enabled = NO;
textField.secureTextEntry = YES;
textField.enabled = YES;
[textField becomeFirstResponder];

編集(dhoerl):iOS 9.3でこれが動作することを確認しましたが、問題があります。プレーンビューで言う3文字を入力し、セキュリティで保護されたテキストに切り替えてから文字を入力すると、3つの既存の文字が消えます。私はすべての種類のトリックをクリアしてから、テキストをリセットして成功しませんでした。最後に、切り取って貼り付けてコントロールを操作するだけで試しました。新しくセキュアモードに切り替わったモードへの貼り付けはうまくいきました。だから私はそれをコードでエミュレートしましたが、今ではすべてうまくいきます-レスポンダで遊ぶ必要もありません。これが私が最終的に終わったものです:

    if textview should go into secure mode and the textfield is not empty {
        textField.text = ""
        textField.secureTextEntry = true

        UIPasteboard.generalPasteboard().string = password
        textField.paste(self)
        UIPasteboard.generalPasteboard().string = ""
    }

私はこの貼り付けを行う必要がないことを好みますが、シームレスにしたい場合は、これが唯一の方法です。

47
MikeR

Mike Rのソリューションは素晴らしいですが、私はこのアプローチを好みます:

BOOL wasFirstResponder;
if ((wasFirstResponder = [passwordField isFirstResponder])) {
    [passwordField resignFirstResponder];
}
// In this example, there is a "show password" toggle
[passwordField setSecureTextEntry:![passwordField isSecureTextEntry]];
if (wasFirstResponder) {
    [passwordField becomeFirstResponder];
}

そうすることで、必要な場合にのみ再びFirstResponderになります。

23
Sandy

私はこの問題に対してrdarを入力しましたが、回避策を見つけました。基本的に、「スタック」コントロールをプログラムで新しいものに置き換える必要があります。最も簡単な方法は、viewDidLoadで既存のコントロールをアーカイブし、必要に応じてアーカイブ解除することです。

// do in viewDidLoad
self.passwordMemberArchive = [NSMutableData data];
NSKeyedArchiver *ka = [[NSKeyedArchiver alloc]       initForWritingWithMutableData:passwordMemberArchive];
[ka encodeObject:password];
[ka finishEncoding];
[ka release];


    // In the action method when you get the UISwitch action message ---
// when your switch changes state
if(isOn) {
    NSString *text = [NSString stringWithString:password.text];
    NSKeyedUnarchiver *kua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    UITextField *tf = [kua decodeObject];
    [kua finishDecoding];
    [kua release];
    tf.inputAccessoryView = textField.inputAccessoryView;
    tf.frame = textField.frame;

    BOOL isFirstResponder = [textField isFirstResponder];
    [scrollView insertSubview:tf aboveSubview:textField];
    if(isFirstResponder) {
        [tf becomeFirstResponder];
    }

    [textField removeFromSuperview];
    self.password = tf;

    if([text length]) {
        if(isFirstResponder) {
            // http://stackoverflow.com/questions/1317929/insert-string-at-cursor-position-of-uitextfield
            // Get a reference to the system pasteboard
            UIPasteboard* lPasteBoard = [UIPasteboard generalPasteboard];
            // Save the current pasteboard contents so we can restore them later
            NSArray* lPasteBoardItems = [lPasteBoard.items copy];
            // Update the system pasteboard with my string
            lPasteBoard.string = text;
            // Paste the pasteboard contents at current cursor location
            [tf paste:self];
            // Restore original pasteboard contents
            lPasteBoard.items = lPasteBoardItems;
            [lPasteBoardItems release];
        } else {
            tf.text = text;
        }
    }
} else {
    textField.secureTextEntry = NO;
}
1
David H

SandyのソリューションのSwiftバージョン。

if #available(iOS 9.2, *) {
    passwordTextField.secureTextEntry = !passwordTextField.secureTextEntry
}
else {
    let wasFirstResponder = passwordTextField.isFirstResponder()
    if wasFirstResponder {
        passwordTextField.resignFirstResponder()
    }

    passwordTextField.secureTextEntry = !passwordTextField.secureTextEntry
    if wasFirstResponder {
        passwordTextField.becomeFirstResponder()
    }
}
0
David Rees

IOSでは、絶対に「ハッキング」しようとしないでください。必要な動作がフレームワークによって提供されない場合は、考えを変えてください。

最初は簡単です^^、次にユーザーはこれに反応しなくなります。次にiOSの次のアップデートで壊れるかどうかわからないため、アプリケーションにとって危険な場合があります。

「ユーザーがセキュリティで保護されたテキストフィールドをタップしているパスワードをユーザーに表示したい場合」、代わりに下部にUILabelを表示できますか?または、パスワードをクリアした確認の警告ボックス?

0
Thomas Decaux