Подтвердить что ты не робот

UITextField secureTextEntry пули с пользовательским шрифтом?

Im использует пользовательский шрифт в UITextField, который включил secureTextEntry. Когда Im вводит в ячейку, я вижу пули в выбранном мной шрифте, но когда поле теряет фокус, эти пули возвращаются к стандартным шрифтом системы. Если я снова коснусь поля, они вернутся к моему шрифту и т.д.

Есть ли способ гарантировать, что они продолжают отображать пользовательские шрифты, даже если поле не в фокусе?

enter image description hereenter image description here

4b9b3361

Ответ 1

Подкласс, который работает с этой проблемой. Создайте произвольный UITextField, затем установите для свойства secure значение YES (через KVC в IB).

На самом деле он реализует комментарий, предложенный lukech. Когда текстовое поле заканчивает редактирование, оно переключается на произвольное текстовое поле, затем задает большое количество точек, а некоторые взломают в text accessor, чтобы всегда получать фактический текст, который имеет поле.

@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-экземплярами, обработкой значений по умолчанию и т.д., но вы, вероятно, получите эту идею.

Ответ 2

Для тех, у кого есть проблемы с потерей пользовательских шрифтов при переключении secureTextEntry, я нашел обход (я использую SDK iOS 8.4). Я пытался сделать переключатель для отображения/скрытия пароля в UITextField. Каждый раз, когда я переключал secureTextEntry = NO, меня настраивал собственный шрифт, и только последний символ показывал правильный шрифт. Что-то фанки, безусловно, происходит с этим, но вот мое решение:

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

Первый ответчик должен быть уволен по какой-то причине. Кажется, вам не нужно уходить с первого ответчика при установке secureTextEntry на YES, только при установке NO.

Ответ 3

Фактическая проблема заключается в том, что в режиме редактирования (UITextField не нарисовывается собственный текст во время редактирования) для рисования отредактированных символов используются пули (U + 2022), а UITextField - черные круги (U + 25CF), Я полагаю, что в стандартных шрифтах эти символы выглядят одинаково.

Здесь альтернативный обходной путь для любого заинтересованного пользователя, который использует подклассу настраиваемого текстового поля, но не требует перехвата текстового свойства или другой специальной конфигурации. ИМО, это держит вещи относительно чистыми.

@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

Ответ 4

Хотя это ошибка iOS (и новая в iOS 7, я должен добавить), у меня есть другой способ обойти это, что можно было бы найти приемлемым. Функциональность все еще немного ухудшена, но не сильно.

В принципе, идея состоит в том, чтобы установить шрифт в семейство шрифтов по умолчанию/стиль всякий раз, когда в поле что-то введено; но когда ничего не введено, установите его на свой собственный шрифт. (Размер шрифта можно оставить в покое, так как это семейство/стиль, а не размер, который является ошибкой.) Ловушка для каждого изменения значения поля и установки шрифта соответственно в это время. Тогда слабый текст "подсказки", когда ничего не введен, имеет шрифт, который вы хотите (пользовательский); но когда что-либо вводится (независимо от того, редактируете вы или нет), будет использоваться значение по умолчанию (Helvetica). Поскольку пули - это пули, это должно выглядеть нормально.

Единственным недостатком является то, что символы, которые вы вводите перед заменой пулями, будут использовать шрифт по умолчанию (Helvetica). Это только на долю секунды за персонажа. Если это приемлемо, то это решение работает.

Ответ 5

Я нашел трюк для этой проблемы.

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

Ответ 6

[passWordTextField resignFirstResponder];
passWordTextField.secureTextEntry = !passWordTextField.secureTextEntry;
[passWordTextField becomeFirstResponder];

Это самый быстрый способ решить эту ошибку!

Ответ 7

iOS действует немного странно, когда дело доходит до пользовательских шрифтов. Попробуйте удалить "Adjust to Fit" для этого текстового поля. Если это не сработает, я предполагаю, что вас беспокоит увеличение размера шрифта.

Простым решением для этого было бы:

- (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.

Ответ 8

Текстовое поле

A 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;
    }
}

Ответ 9

Я рекомендую resignFirstResponder перед тем, как вы измените scureTextEntry, а затем снова запустите FirstResponder, когда он будет опубликован здесь: fooobar.com/info/140333/...