UITextField
がオンになっているsecureTextEntry
でカスタムフォントを使用しています。セルに入力すると、選択したフォントで箇条書きが表示されますが、フィールドがフォーカスを失うと、それらの箇条書きはシステムの標準フォントに戻ります。フィールドをもう一度タップすると、フォントが元のフォントに戻ります。
フィールドがフォーカスされていなくても、カスタムフォントの箇条書きが引き続き表示されるようにする方法はありますか?
この問題を回避するサブクラス。 任意のUITextField
を作成し、secure
プロパティをYES
に設定します(IBのKVCを介して) )。
実際には lukech によって提案されたコメントを実装しています。テキストフィールドが編集を終了すると、任意のテキストフィールドに切り替わり、大量のドットを設定し、text
アクセサーをハックして、フィールドが保持する実際のテキストを常に取得します。
@interface SecureTextFieldWithCustomFont : UITextField
@property (nonatomic) BOOL secure;
@property (nonatomic, strong) NSString *actualText;
@end
@implementation SecureTextFieldWithCustomFont
-(void)awakeFromNib
{
[super awakeFromNib];
if (self.secureTextEntry)
{
// Listen for changes.
[self addTarget:self action:@selector(editingDidBegin) forControlEvents:UIControlEventEditingDidBegin];
[self addTarget:self action:@selector(editingDidChange) forControlEvents:UIControlEventEditingChanged];
[self addTarget:self action:@selector(editingDidFinish) forControlEvents:UIControlEventEditingDidEnd];
}
}
-(NSString*)text
{
if (self.editing || self.secure == NO)
{ return [super text]; }
else
{ return self.actualText; }
}
-(void)editingDidBegin
{
self.secureTextEntry = YES;
self.text = self.actualText;
}
-(void)editingDidChange
{ self.actualText = self.text; }
-(void)editingDidFinish
{
self.secureTextEntry = NO;
self.actualText = self.text;
self.text = [self dotPlaceholder];
}
-(NSString*)dotPlaceholder
{
int index = 0;
NSMutableString *dots = @"".mutableCopy;
while (index < self.text.length)
{ [dots appendString:@"•"]; index++; }
return dots;
}
@end
NIB以外のインスタンス化、デフォルト値の処理などで機能するように拡張できますが、おそらくあなたはそのアイデアを理解しているでしょう。
SecureTextEntryを切り替えるときにカスタムフォントが失われる問題がある場合は、回避策を見つけました(iOS 8.4 SDKを使用しています)。 UITextFieldでパスワードの表示/非表示を切り替えるトグルを作成しようとしました。切り替えるたびにsecureTextEntry = NO
カスタムフォントが機能しなくなり、最後の文字だけが正しいフォントを示しました。ファンキーな何かがこれで間違いなく起こっていますが、これが私の解決策です:
-(void)showPassword {
[self.textField resignFirstResponder];
self.textField.secureTextEntry = NO;
}
何らかの理由でファーストレスポンダを辞任する必要があります。 secureTextEntryをYESに設定する場合、NOに設定する場合にのみ、ファーストレスポンダを辞任する必要はないようです。
実際の問題は、編集ビュー(UITextField
しない編集中に独自のテキストを描画)が箇条書き(U + 2022)を使用して編集された文字を描画する一方で、UITextField
は黒丸(U + 25CF)を使用します。デフォルトのフォントでは、これらの文字は同じに見えると思います。
カスタムテキストフィールドサブクラスを使用するが、textプロパティやその他の特別な構成を調整する必要がない、興味のある人のための代替の回避策を次に示します。 IMO、これは比較的クリーンな状態を保ちます。
@interface MyTextField : UITextField
@end
@implementation MyTextField
- (void)drawTextInRect:(CGRect)rect
{
if (self.isSecureTextEntry)
{
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = self.textAlignment;
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
[attributes setValue:self.font forKey:NSFontAttributeName];
[attributes setValue:self.textColor forKey:NSForegroundColorAttributeName];
[attributes setValue:paragraphStyle forKey:NSParagraphStyleAttributeName];
CGSize textSize = [self.text sizeWithAttributes:attributes];
rect = CGRectInset(rect, 0, (CGRectGetHeight(rect) - textSize.height) * 0.5);
rect.Origin.y = floorf(rect.Origin.y);
NSMutableString *redactedText = [NSMutableString new];
while (redactedText.length < self.text.length)
{
[redactedText appendString:@"\u2022"];
}
[redactedText drawInRect:rect withAttributes:attributes];
}
else
{
[super drawTextInRect:rect];
}
}
@end
これはiOSのバグです(そしてiOS 7の新機能ですが、追加する必要があります)が、問題を回避するための別の方法があり、それで問題ない場合もあります。機能はまだ少し低下していますが、それほど低下していません。
基本的には、フィールドに何かが入力されるたびに、フォントをデフォルトのフォントファミリー/スタイルに設定するという考え方です。ただし、何も入力しない場合は、カスタムフォントに設定します。 (フォントサイズは、サイズではなくファミリ/スタイルであるため、そのままにすることができます。バグが発生します。)フィールドの値のすべての変更をトラップし、そのときにそれに応じてフォントを設定します。次に、何も入力されないときのかすかな「ヒント」テキストに、必要なフォント(カスタム)が含まれます。ただし、何かを入力すると(編集中かどうかにかかわらず)、デフォルト(Helvetica)が使用されます。弾丸は弾丸なので、これは問題なく見えるはずです。
欠点の1つは、箇条書きに置き換えられる前に入力する文字がデフォルトのフォント(Helvetica)を使用することです。ただし、これは1文字あたりほんの一瞬です。それが許容できる場合、このソリューションは機能します。
[passWordTextField resignFirstResponder];
passWordTextField.secureTextEntry = !passWordTextField.secureTextEntry;
[passWordTextField becomeFirstResponder];
これがこのバグを解決する最も速い方法です!
この問題のトリックを見つけました。
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if ([textField tag]== TAG_PASS || [textField tag]== TAG_CPASS)
{
// To fix password dot size
if ([[textField text] isEqualToString:@"" ])
{
[textField setText:@" "];
[textField resignFirstResponder];
[textField becomeFirstResponder];
[textField setText:@""];
}
}
}
secureTextEntry
テキストフィールドは完全に回避できます。
NSString *pin = @"";
BOOL pasting = FALSE;
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(!pasting) {
pin = [pin stringByReplacingCharactersInRange:range withString:string];
// Bail out when deleting a character
if([string length] == 0) {
return YES;
}
pasting = TRUE;
[textField paste:@"●"];
return NO;
} else {
pasting = FALSE;
return YES;
}
}
カスタムフォントに関しては、iOSは少し奇妙な動作をしています。そのテキストフィールドの「合わせる」を削除してみてください。それでもうまくいかない場合は、フォントのサイズが大きくなっていることが原因と思われます。
そのための簡単な解決策は次のとおりです。
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if(textField.secureTextEntry)
{
[textField setFont:[UIFont fontWithName:@"Helvetica-Bold" size:10.0]];
}
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if(textField.secureTextEntry)
{
[textField setFont:[UIFont fontWithName:@"Helvetica-Bold" size:10.0]];
}
}
UITextField
へのフォーカスを失ったときにサイズが変更されていないように見えるように、少しサイズを変更する必要があります。
編集した質問のように文字間の大きな間隔の問題がある場合、最も簡単な(そして少し醜い)解決策は、上記のサイズと間隔に一致し、ユーザーが入力した文字の量に一致するBullet画像を作成することです。ユーザーがUITextField
を離れると表示されます。
ScureTextEntryを変更する前にresignFirstResponderにしてから、FirstFirstResponderになることをお勧めします。ここに掲載されています。 https://stackoverflow.com/a/34777286/1151916