Search code examples
iosobjective-ccocoa-touchuikituitextfield

UITextField secureTextEntry bullets with a custom font?


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


Solution

  • A subclass that works this issue around. Create an arbitrary UITextField, then set the secure property to YES (via KVC in IB).

    Actually it implements a comment suggested by lukech. When textfield ends editing, it switches to an arbitrary textfield, then set a bulk of dots into, and some hack in text accessor to always get the actual text the field holds.

    @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
    

    May be augmented to work with non NIB instantiations, handling default values, etc, but you probably get the idea.