matCode
matCode

Reputation: 139

UiTextField changes font while editing in Swift 1.2 & 2.0

I have a UITextField with a custom font, everything worked fine until Swift update to 1.2 and 2.0. Afterwards, each time I try to edit a text field, it changes its font to a different one that seems a sort of Times New Roman. Does anyone have experience of that?

Upvotes: 9

Views: 3504

Answers (6)

Tyler
Tyler

Reputation: 19848

All of these answers pretty much work, but I had to use a different solution to achieve the results I needed, considering I'm using a custom font.

You need to make the text field attributed in the storyboard inspector pane for the UITextField, as follows:

attributed selected in inspector

Then, in code, you need to manage the toggling of the visibility, setting the attributed text each time, to ensure its properly formatted. I also resignFirstResponder() on the field just to take care of some positioning glitch that I still haven't figured out yet.

func toggleShowPass() {
    self.showing = !showing

    txtpassword.secureTextEntry = !showing
    textFieldPassword.resignFirstResponder()

    let string = textFieldPassword.text!
    let attrString = NSMutableAttributedString(string: string)

    textFieldPassword.addAttribute(NSFontAttributeName, value: UIFont(name: "AvenirNext-Regular", size: 16.0)!, range: NSMakeRange(0, string.characters.count))
    textFieldPassword.attributedText = attrString

}

Upvotes: 1

Alexander
Alexander

Reputation: 583

I came across this same issue and figured out a solution. The problem boils down to setSecureTextEntry changing the font when it is set, and not changing it back when it is unset. In fact, you can never change the font back as long as your UITextField has first responder.

The trick is to resignFirstResponder before you call setSecureTextEntry: and then becomeFirstResponder again. This will work (as of iOS 9.2), but it triggers the keyboard show/hide animation and will cause the screen to "shake". To get around that, you'll need to kill the keyboard animation as well.

Here's my full solution:

- (void)setSecureTextEntry:(BOOL)secureTextEntry {

    __weak typeof(self) weakSelf = self;
    [UIView performWithoutAnimation:^{

        BOOL resumeResponder = NO;
        if([[weakSelf textEntryField] isFirstResponder]) {
            resumeResponder = YES;
            [[weakSelf textEntryField] resignFirstResponder];
        }

        [[weakSelf textEntryField] setSecureTextEntry:secureTextEntry];

        if(resumeResponder) {
            [[weakSelf textEntryField] becomeFirstResponder];
        }
    }];
}

PS: This isn't a Swift bug. It's a UIKit bug. I had the same issue with Objective-C.

Upvotes: 11

Daniel Galasko
Daniel Galasko

Reputation: 24237

Since I used custom fonts we need to preserve the original font. Create an extension to UITextField:

extension UITextField {
    func enablePasswordModeWithShowHide() {
        secureTextEntry = false
        let showButton = UIButton(type: UIButtonType.System)
        showButton.setTitle("HIDE", forState: .Normal)
        showButton.titleLabel?.textAlignment = .Right
        showButton.sizeToFit()
        rightView = showButton
        rightViewMode = .Always
        showButton.addTarget(self, action: "handleShowHideTapped", forControlEvents: .TouchUpInside)
        showButton.tintColor = UIColor.blackColor()
    }

    func handleShowHideTapped() {
        secureTextEntry = !secureTextEntry
        let font = self.font
        self.font = nil
        self.font = font
        if let oldText = text {
            text = "";
            text = oldText;
        }

        if let button = rightView as? UIButton {
            button.setTitle(secureTextEntry ? "SHOW" : "HIDE", forState: .Normal)
            button.sizeToFit()
        }
    }
}

Where it could be implemented like this:

passwordTextField.enablePasswordModeWithShowHide()

Upvotes: 2

Leena
Leena

Reputation: 2676

I had to apply the following solution with latest Xcode 7.1.1 which actually worked in my case I suspect this issue is of framework.

- (IBAction)btnPasswordShowAction:(id)sender {


        self.txtPassword.secureTextEntry = !self.txtPassword.secureTextEntry;

        NSString *tmpString = self.txtPassword.text;
        self.txtPassword.text = @" ";
        self.txtPassword.text = tmpString;

       [self.txtPassword setFont:nil];
       self.txtPassword.font = [UIFont fontWithName:@"OpenSans-Regular" size:16.0];
  }

 #pragma mark -  Textfield Delegate Methods

 - (void)textFieldDidBeginEditing:(UITextField *)textField
   {
       [self.txtPassword setFont:nil];
       self.txtPassword.font = [UIFont fontWithName:@"OpenSans-Regular" size:16.0];
   }


   - (BOOL)textFieldShouldEndEditing:(UITextField *)textField
    {
        [self.txtPassword setFont:nil];
        self.txtPassword.font = [UIFont fontWithName:@"OpenSans-Regular" size:16.0];
         return YES;
   } 

Upvotes: 0

Payal
Payal

Reputation: 116

Set defaultTextAttributes with custom font attribute after toggling the secureTextEntry flag

NSDictionary *attrsDictionary = @{ NSFontAttributeName://customfont};
_passwordtextfield.defaultTextAttributes = attrsDictionary;

Upvotes: 0

Abhijeet
Abhijeet

Reputation: 8771

I had a weird case of fonts changing its size and font type, when secureTextEntry for an UiTextField was toggled by using a button action. enter image description here Had to explicitly manage font for the UiTextField by using these lines of code:

password.font = UIFont(name: "systemFont", size: 14)
password.font = UIFont.systemFontOfSize(14)

Complete Code used in the Show Password Button:

//Function associated with the button for show password option
@IBAction func switchShowPasswordAction(sender: AnyObject) {
        if showPassword{
            showPassword  = false
            password.secureTextEntry = !showPassword

        }else{
            showPassword = true
            password.secureTextEntry = !showPassword
        }

        //Changing font fix
        password.font = UIFont(name: "systemFont", size: 14)
        password.font = UIFont.systemFontOfSize(14)
}

Post applying this change: enter image description here

Upvotes: 7

Related Questions