iOS 11 disable password autofill accessory view option?

49,250

Solution 1

iOS 11 & 12 & 13 - Swift 4.2 & 5 (Updated):

if #available(iOS 12, *) {
    // iOS 12 & 13: Not the best solution, but it works.
    passwordTextField.textContentType = .oneTimeCode
} else {
    // iOS 11: Disables the autofill accessory view. 
    // For more information see the explanation below.
    emailTextField.textContentType = .init(rawValue: "")
    passwordTextField.textContentType = .init(rawValue: "")
}

iOS 11 explanation:

Make sure you setup all of your UITextField objects like this.

If you have for example an UITextField object where the user must enter his email address and another one where the user must enter his password assign UITextContentType("") to both of their textContentType property. Otherwise it will not work and the autoFill accessory view will still be shown.

Solution 2

iOS 12 seems to recognise password textFields also by isSecureTextEntry property and not just by textContentType property, so making this accessory view disappear is not really possible unless you both set textContentType to nothing, and remove the secureEntry feature (and cause a security flaw in your app) which then prevents iOS 12 to recognise the textField as a password textField and show this annoying accessory view.

In my case the accessory caused a bug which made my app unresponsive when tapped (Which also got my app rejected in app review process). So I had to remove this feature. I didn't want to give on up this security feature so I had to solve things by my self.

The idea is to remove the secureEntry feature but add it by yourself manually. It did worked:

enter image description here


It can be done like that:

Swift 4 way:

First, as answered here, set textContentType to nothing:

if #available(iOS 10.0, *) {
    passwordText.textContentType = UITextContentType("")
    emailText.textContentType = UITextContentType("")
}

Than, declare a String variable which will later contain our textField real content:

var passwordValue = ""

Add a target to the passwordTextField, which will be called each time the textField content changes:

passwordText.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)

Now That's what will do the magic, declare the function that will handle the text replacements:

@objc func textFieldDidChange(_ textField: UITextField) {
    if textField.text!.count > 1 {
        // User did copy & paste
        if passwordValue.count == 0 { // Pasted into an empty textField
            passwordValue = String(textField.text!)
        } else { // Pasted to a non empty textField
            passwordValue += textField.text!.substring(from: passwordValue.count)
        }
    } else {
        // User did input by keypad
        if textField.text!.count > passwordValue.count { // Added chars
            passwordValue += String(textField.text!.last!)
        } else if textField.text!.count < passwordValue.count { // Removed chars
            passwordValue = String(passwordValue.dropLast())
        }
    }
    self.passwordText.text = String(repeating: "•", count: self.passwordText.text!.count)
}

Finally, Set textField's autocorrectionType to .no to remove predictive text:

passwordText.autocorrectionType = .no

That's it, use passwordValue to perform your login.

Hope it'll help someone.

UPDATE

It catches pasted values also, forgot to add it before.

Solution 3

The feature can be disabled by specifying a content type that is neither username nor password. For example, if the user should enter an email address, you could use

usernameTextField?.textContentType = .emailAddress

Solution 4

in response to @Gal Shahar Answer.

iOS 12 recognise password textFields by isSecureTextEntry property and not just by textContentType property.

Way Around to bypass Auto-fill Suggestion.

  1. set isSecureTextEntry property to false.

self.passwordTextField.secureTextEntry = NO;

  1. Add a UITextField Delegate Method and enable the isSecureTextEntry property.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField == self.passwordTextField && !self.passwordTextField.secureTextEntry) {
        self.passwordTextField.secureTextEntry = YES;
    }

    return YES;
}

NOTE: - Do NOT Use shouldBeginEditing UITextField delegate method it Will Still show Auto-filling Suggestion. Do NOT Use textFieldDidChange UITextField delegate method it Will Auto-delete the first charachter as the it Will happen after the first charachter is displayed. And 'secureTextEntry' will empty the field.

Solution 5

You can add extension for UITextContentType like this

extension UITextContentType {
    public static let unspecified = UITextContentType("unspecified")
}

after that, you can use it

if #available(iOS 10.0, *) {
    passwordField.textContentType = .unspecified
}
Share:
49,250
zumzum
Author by

zumzum

Updated on July 08, 2022

Comments

  • zumzum
    zumzum almost 2 years

    As of now I would like to opt out of the new option iOS 11 gives, that is to suggest passwords in the app. When I run the app on iOS 11 I get the autofill option on top of the keyboard and my username and password textfield don't even show up.

    So, my question is, how can I disable the new password autofill feature all together so the key on the keyboard is not shown at all and the overall behavior is the same as pre iOS 11?

    enter image description here

  • stktrc
    stktrc almost 7 years
    This type of 'answer' should be reserved for the comments section, as it doesn't give an actual answer or link to any reference documentation from apple etc. Welcome to SO though!
  • zumzum
    zumzum almost 7 years
    no solution yet. Nothing listed here worked well for me.
  • Brad Root
    Brad Root almost 7 years
    Interestingly I have an email address field above a password field, and the email address field offers an auto-complete.
  • Sahil
    Sahil almost 7 years
    @BradRoot change your password field textContentype too! if your email is already saved in keychain then it will show the info in quickbar, so better to user .nickname or try this code if #available(iOS 10.0, *) { self.passwordTextField.textContentType = UITextContentType.init(rawValue: "") } else { // Fallback on earlier versions }
  • matm
    matm over 6 years
    It's available form iOS 10, not iOS 11.
  • pfandrade
    pfandrade almost 6 years
    Does this still work on the latest iOS 12 beta for you?
  • Miguel Cabeça
    Miguel Cabeça almost 6 years
    No it does not. On iOS 12 it detects this field as a new password field and suggests a new strong password (new iOS 12 feature). I actually want this behavior in my case, so I'm tagging this password field with the new iOS 12 newPassword UITextContentType . I don't know how to avoid this new behavior though.
  • Daniel Jones
    Daniel Jones almost 6 years
    For iOS 12 beta, if use: textContentType = UITextContentType.oneTimeCode. Then, it doesn't have the keychain on the keyboard. It seems to work fine for me without any side effects. If you use .newPassword, that also works, but then it asks you to save the password once you finish with the password.
  • Baran Emre
    Baran Emre almost 6 years
    @GalShahar I can't test it right now but here is my suggestion: iOS 12 introduces a new UITextContentType which is called newPassword (see: developer.apple.com/documentation/uikit/uitextcontenttype/…)‌​. Try setting the password text fields content type to this type. I guess iOS will not show the autofill accessory view then, because the user is forced to setup a new password and not use/access one that was setup before by using the autofill accessory view. Right now this is only theory. I'm not sure whether this will work, but let me know whether it does!
  • sandpat
    sandpat almost 6 years
    Super! Nice hack buddy! shame that iOS makes us hack rather than providing cleaner ways to do the most basic things. This should be the accepted answer.
  • Baran Emre
    Baran Emre over 5 years
    Okay guys forget about what I wrote about iOS 12. Setting UITextContentType to newPassword does not work. I tried the solution of @GalShahar, but I didn't like it. Instead I'm setting the UITextContentType to oneTimeCode . That works for now.
  • da1
    da1 over 5 years
    For iOS 12, I had to set isSecureTextEntry to false first in addition to set UITextContentType to oneTimeCode. We can set isSecureTextEntry to whatever we want once they start typing the text field.
  • Baran Emre
    Baran Emre over 5 years
    @da1 We are setting .isSecureTextEntry to true before setting textContentType to .oneTimeCode and it works as expected. I don't know how your code looks like, but when initializing the text field the order of setting up it's properties is not important.
  • Eric Aya
    Eric Aya over 5 years
    This is the same as Bem’s answer.
  • Kumaresan P
    Kumaresan P over 5 years
    it doesn't work when change input focus from user name to password
  • Baran Emre
    Baran Emre over 5 years
    @KumaresanP try setting textContentType on both of your text fields (user name + password)
  • Kumaresan P
    Kumaresan P over 5 years
    @Bem yes did both works partially, problem is when switch from normal text type to secure text and do wise versa
  • Baran Emre
    Baran Emre over 5 years
    @KumaresanP why do you switch the textContentType? Marking your text field with isSecureTextEntry should also work. Or do you use one text field for both entries (email address + password -> like when the user did enter his email address the same text field is used to enter the password)?
  • Kumaresan P
    Kumaresan P over 5 years
    @Bem actually doing toggle between secure text entry as false and true to recreate it.
  • Baran Emre
    Baran Emre over 5 years
    @KumaresanP I think this could be the issue. Instead of switching isSecureTextEntry too true and false create two text fields. One for your the user's email address input and one for the user's password input. Make sure to setup both correctly with the suggested textContentType above. Add and position the password field on top of the email address input field. Set the isHidden property of the password text field to true and when the user is finished with the email address you can set isHidden of the password text field to false and of the email address text field input to true.
  • ekashking
    ekashking about 4 years
    This not only solves a discussed problem but also solves the problem of misreading a keyboard height from the UIKeyboardWillShowNotification when initially tapping on the password field. Great answer.
  • Sandeep Maurya
    Sandeep Maurya almost 4 years
    passwordTextField.textContentType = .oneTimeCode not works with iphone 6s ios 13.5
  • Baran Emre
    Baran Emre almost 4 years
    @SandeepMaurya Did you found a solution?
  • Sandeep Maurya
    Sandeep Maurya almost 4 years
    @BaranEmre no, I'm not what I'm doing is initialy leave textfield as normal. and once user start typing I change textfield to isSecureText = true. tried all solutions not a single work
  • youjin
    youjin over 2 years
    Downvoted because the logic makes no sense. Why would if textField.text!.count > 1 mean that a user copy pasted? And if a user deleted characters, passwordValue.dropLast() assumes a user always deletes from the end. What if a user deletes a range of characters in the middle somewhere?