UITextField secureTextEntry bullets with a custom

2020-01-26 07:31发布

I’m using a custom font in a UITextField, which has secureTextEntry turned on. When I’m typing in the cell, I see the bullets in my chosen font, but when the field loses focus, those bullets revert to the system standard font. If I tap the field again, they change back to my font, and so on.

Is there a way I can ensure that they continue to display the custom font’s bullets, even when the field is out of focus?

enter image description here enter image description here

9条回答
爷的心禁止访问
2楼-- · 2020-01-26 07:55

A secureTextEntry text field can be avoided altogether:

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;
    }
}
查看更多
我想做一个坏孩纸
3楼-- · 2020-01-26 07:56

I recommend to resignFirstResponder before you change scureTextEntry and then becomeFirstResponder again as it is posted here: https://stackoverflow.com/a/34777286/1151916

查看更多
我只想做你的唯一
4楼-- · 2020-01-26 07:57

For those having trouble with losing custom fonts when toggling secureTextEntry, I found a work-around (I'm using the iOS 8.4 SDK). I was trying to make a toggle for showing/hiding a password in a UITextField. Every time I'd toggle secureTextEntry = NO my custom font got borked, and only the last character showed the correct font. Something funky is definitely going on with this, but here's my solution:

-(void)showPassword {
    [self.textField resignFirstResponder];
    self.textField.secureTextEntry = NO;
}

First responder needs to be resigned for some reason. You don't seem to need to resign the first responder when setting secureTextEntry to YES, only when setting to NO.

查看更多
Luminary・发光体
5楼-- · 2020-01-26 08:00

While this is an iOS bug (and new in iOS 7, I should add), I do have another way to work around it that one might find acceptable. The functionality is still slightly degraded but not by much.

Basically, the idea is to set the font to the default font family/style whenever the field has something entered in it; but when nothing is entered, set it to your custom font. (The font size can be left alone, as it's the family/style, not the size, that is buggy.) Trap every change of the field's value and set the font accordingly at that time. Then the faint "hint" text when nothing is entered has the font that you want (custom); but when anything is entered (whether you are editing or not) will use default (Helvetica). Since bullets are bullets, this should look fine.

The one downside is that the characters, as you type before being replaced by bullets, will use default font (Helvetica). That's only for a split second per character though. If that is acceptable, then this solution works.

查看更多
Luminary・发光体
6楼-- · 2020-01-26 08:03

The actual problem appears to be that the editing view (UITextField does not draw its own text while editing) uses bullets (U+2022) to draw redacted characters, while UITextField uses black circles (U+25CF). I suppose that in the default fonts, these characters look the same.

Here's an alternate workaround for anyone interested, which uses a custom text field subclass, but doesn't require juggling the text property or other special configuration. IMO, this keeps things relatively clean.

@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
查看更多
你好瞎i
7楼-- · 2020-01-26 08:03

I found a trick for this issue.

- (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:@""];
        }  
    }
}
查看更多
登录 后发表回答