35

表示/非表示モードを切り替えるボタンがあります (つまり、UITextField を secureTextEntry NO と YES の間で切り替えます)。その目的は、ユーザーが入力しているパスワードを表示できるようにすることです。

私はここの例に従いました (投票数が最も多い): UITextField secureTextEntry - YES から NO に移行しますが、YES に戻しても効果はありません

しかし、secureTextEntry を NO に設定すると、そこに書かれたテキストの末尾にスペースができてしまいます。secureTextEntry を YES に設定すると、これは問題にならないようです。

たとえば、setSecureTextEntry が NO に設定されているときに「mypassword」というテキストを入力してから YES に切り替えると、ユーザーには ********** (10 個のドット) が表示されますが、これは正しいです。SecureTextEntry を NO に設定すると、ユーザーには "mypassword " が表示されます (最後にスペースがあるか、少なくともカーソルが 1 つ右にスペースを移動しました)。

重要な注意: デバッガーでは、次のように、テキストの文字列値が末尾のスペースなしで表示されます。

(lldb) expr self.passwordText.text
(NSString *) $0 = 0x1d8450e0 @"mypassword"

空白をトリミングしようとしましたが(UITextField の中間の空白を避けるため)、効果はありませんでした。

4

18 に答える 18

13

PRE-iOS-8.0 (古いソリューション) ... ボタンのアクション メソッド ( secureTextEntryYES と NO の切り替え) で、UITextFieldtextプロパティを現在のtext値に設定するだけです。これは冗長でハックのように見えるかもしれませんが、これによりカーソルが正しい位置に再描画されます。ボタンのアクション メソッドが今どのように見えるかの例を次に示します...

-(void)toggleButtonPressed:(UIButton*)sender
{
    // Toggle between secure and not-so-secure entry
    self.toggleButton.selected = !self.toggleButton.selected;
    self.textfield.secureTextEntry = !self.toggleButton.selected;

    // * Redundant (but necessary) line *
    [self.textfield setText:self.textfield.text];
}

POST-iOS-8.0... iOS 8.0 の時点でUITextFieldtext現在の文字列値と等しい文字列で呼び出されたときに、セッターがカーソルを再描画しなくなったようです。ここで、これをさらに一歩進めて、text再度リセットする前に実際に値を変更する必要があります。setText:上記の行をこれらの行のようなものに置き換えます。

// * Extra redundant (but necessary) lines *
NSString *currentText = self.textfield.text;
[self.textfield setText:@"Arbitrary string..."]; // Change the value
[self.textfield setText:currentText]; // Reset the value
于 2014-03-20T15:33:23.033 に答える
6

iOS でこのバグを回避するには、次の手順を実行するだけです (すべての iOS バージョンで機能します)。

- (IBAction)toggleSecureTextEntry:(UIButton *)button
{
    self.textField.secureTextEntry = !self.textField.secureTextEntry;
    NSString *originalText = self.textField.text;
    self.textField.text = nil;
    self.textField.text = originalText;
}
于 2015-06-16T10:35:51.320 に答える
4

次のように修正できます。

NSString *currentText = self.textfield.text;
self.textfield.text = @"";
self.textfield.text = currentText;
于 2015-09-29T15:13:54.657 に答える
3

これはiOS 8で機能します

if (self.passwordTextField.secureTextEntry) {
    // Display password and keep selected text range
    UITextRange *selectedTextRange = self.passwordTextField.selectedTextRange;
    NSString *password = self.passwordTextField.text;
    self.passwordTextField.secureTextEntry = NO;
    self.passwordTextField.text = [@"" stringByPaddingToLength:password.length withString:@" " startingAtIndex:0]; // Done for carret redrawing
    self.passwordTextField.text = password;
    self.passwordTextField.selectedTextRange = selectedTextRange;
}
else {
    // Hide password and keep selected text range
    UITextRange *selectedTextRange = self.passwordTextField.selectedTextRange;
    NSString *password = self.passwordTextField.text;
    self.passwordTextField.secureTextEntry = YES;
    self.passwordTextField.text = [@"" stringByPaddingToLength:password.length withString:@" " startingAtIndex:0]; // Done for carret redrawing
    self.passwordTextField.text = password;
    self.passwordTextField.selectedTextRange = selectedTextRange;
}
于 2014-10-09T09:10:24.500 に答える
2

これは、self.passwordText が UITextField である場合に、この問題を解決する別の可能性です。

if (self.passwordText.isFirstResponder) {
    [self.passwordText resignFirstResponder];
    [self.passwordText becomeFirstResponder];
}
于 2015-02-20T14:10:35.827 に答える
2

textfield.secureTextEntry プロパティを変更しても、キャレットの位置は更新されません。これを修正するために、以下のコードは IOS 8 より前に動作していました。

pwdTextField.text  = pwdTextField.text

今はそうではありません。IOS 8 は新しい値が古い値と等しいことを検出し、何もしないようです。したがって、再び機能させるには、実際に値を変更する必要があります。これが私のために働く迅速なバージョンです。

let str = pwdTextField.text
pwdTextField.text = str + " "
pwdTextField.text = str
于 2014-12-03T20:17:48.860 に答える
1

これは私の場合に機能します

    BOOL wasFirstResponder = [self.passwordTextField isFirstResponder];
    if([self.passwordTextField isSecureTextEntry])
    {
        //This three lines are key
        self.passwordTextField.delegate = nil;
        [self.passwordTextField resignFirstResponder];
        self.passwordTextField.delegate = self;
    }

    [self.passwordTextField setSecureTextEntry: !self.passwordTextField.isSecureTextEntry];
    if(wasFirstResponder)
        [self.passwordTextField becomeFirstResponder];
于 2015-06-18T13:19:26.920 に答える
1

参照リンクの 2 番目のソリューションは、実装すると、余分なスペースを追加しないという望ましい動作をするようです。

https://stackoverflow.com/a/8495888/738190

于 2013-01-08T19:21:26.160 に答える
0

カーソルを正しく再配置するには、フォント属性を設定するとうまくいくようです。

// Hack to update cursor position
self.passwordTf.defaultTextAttributes = @{NSFontAttributeName: textFieldFont, NSForegroundColorAttributeName: textFieldColor};

// Change secure entry
self.passwordTf.secureTextEntry = !self.passwordTf.secureTextEntry;

iOS8、iOS9でテスト済み。それが役に立てば幸い!

于 2015-09-26T09:37:45.210 に答える
0

スイフト4

バグはレーダーにあり、回避策の説明もあります: http://www.openradar.me/38465011

キャレット(カーソル)の位置をネイティブに更新する一時的な回避策の一部を次に示します。

// update caret position
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
    let (beginning, end) = (self.beginningOfDocument, self.endOfDocument)

    self.selectedTextRange = self.textRange(from: beginning, to: end)
    self.selectedTextRange = self.textRange(from: end, to: end)
}
于 2018-08-17T12:54:16.263 に答える