it-swarm.com.ru

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

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

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

enter image description hereenter image description here

39
Luke

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

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

17
Geri

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

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

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

11
Joshua Haines

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

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

@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
9
Austin

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

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

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

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

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

1
AaronTKD

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

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

Текстовое поле 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;
    }
}
0
Randomblue

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.

0
Segev

Я рекомендую перезапустить ResignFirstResponder, прежде чем менять scureTextEntry, а затем снова статьFirstResponder, как это опубликовано здесь: https://stackoverflow.com/a/34777286/1151916

0
Ramis