UITextField使用自定义字体的secureTextEntry项目符号?

时间:2014-01-07 10:38:23

标签: ios objective-c cocoa-touch uikit uitextfield

我在UITextField中使用自定义字体,其中secureTextEntry已开启。当我在单元格中键入时,我会看到所选字体中的项目符号,但是当该字段失去焦点时,这些项目符号将恢复为系统标准字体。如果我再次点击该字段,它们将更改回我的字体,依此类推。

有没有办法可以确保他们继续显示自定义字体的项目符号,即使字段没有焦点?

enter image description here enter image description here

10 个答案:

答案 0 :(得分:17)

解决此问题的子类。创建任意UITextField ,然后将secure属性设置为YES(通过IB中的KVC)。

实际上它实现了lukech建议的评论。当textfield结束编辑时,它会切换到任意文本字段,然后将大量的点设置为,并在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实例化,处理默认值等,但您可能会理解。

答案 1 :(得分:11)

对于那些在切换secureTextEntry时丢失自定义字体有困难的人,我找到了解决办法(我使用的是iOS 8.4 SDK)。我试图在UITextField中显示/隐藏密码。每次我切换secureTextEntry = NO我的自定义字体都被borked,并且只有最后一个字符显示正确的字体。时髦的东西肯定会继续下去,但这是我的解决方案:

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

第一响应者因某种原因需要辞职。当设置为NO时,您似乎不需要在将secureTextEntry设置为YES时重新签署第一个响应者。

答案 2 :(得分:9)

实际问题似乎是编辑视图(UITextField 在编辑时不绘制自己的文字)使用项目符号(U + 2022)绘制编辑后的字符,而{{ 1}}使用黑色圆圈(U + 25CF)。我想在默认字体中,这些字符看起来是一样的。

这是对任何感兴趣的人的替代解决方法,它使用自定义文本字段子类,但不需要处理文本属性或其他特殊配置。国际海事组织,这使事情保持相对清洁。

UITextField

答案 3 :(得分:3)

虽然这是一个iOS错误(在iOS 7中是新的,我应该添加),但我确实有另一种方法来解决它可能会被接受的问题。功能仍然略有下降但不是很多。

基本上,只要字段中输入了某些内容,就可以将字体设置为默认字体系列/样式;但是当没有输入任何内容时,请将其设置为自定义字体。 (字体大小可以单独留下,因为它是系列/样式,而不是大小,有缺陷。)捕获字段值的每次更改并在此时相应地设置字体。然后,当没有输入任何内容时,微弱的“提示”文本具有您想要的字体(自定义);但是当输入任何内容时(无论您是否正在编辑)都将使用默认值(Helvetica)。由于子弹是子弹,这应该看起来不错。

一个缺点是,在被项目符号替换之前输入的字符将使用默认字体(Helvetica)。这只是每个角色的瞬间。如果这是可以接受的,那么这个解决方案就可以了。

答案 4 :(得分:1)

我找到了解决这个问题的技巧。

- (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:@""];
        }  
    }
}

答案 5 :(得分:1)

sr_no

这是解决此错误的最快方法!

答案 6 :(得分:0)

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时看起来没有尺寸变化。

如果编辑问题中的字符之间存在重大间距问题,那么最简单(也有点难看)的解决方案是创建一个匹配上述尺寸和尺寸的子弹图像。间距和匹配用户输入的字符数量,当用户离开UITextField时会显示。

答案 7 :(得分:0)

可以完全避免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;
    }
}

答案 8 :(得分:0)

我建议您在更改scureTextEntry之前再使用resignFirstResponder,然后在此处发布时再次成为FirstFirstResponder:https://stackoverflow.com/a/34777286/1151916

答案 9 :(得分:0)

Swift 5 和 iOS 14 即将推出,但自定义字体的 isSecureTextEntry 设置为 true 仍然显示错误大小的项目符号,尽管实际前导字母的大小正确。

除了在密码处于安全模式时将字体设置为系统字体的hacky解决方法之外,堆栈溢出的所有解决方案都没有对我有用。

  if textField.isSecureTextEntry {
            self.textField.font = UIFont.systemFont(ofSize: 17)
    } else {
        self.textField.font = UIFont(name: "Roboto-Regular", size: 17)
    }