Ab sofort möchte ich die neue Option von iOS 11 deaktivieren, dh Passwörter in der App vorschlagen. Wenn ich die App unter iOS 11 ausführe, wird oben auf der Tastatur die Option zum automatischen Ausfüllen angezeigt, und mein Textfeld für Benutzername und Kennwort wird nicht einmal angezeigt.
Meine Frage ist also, wie ich die neue Funktion zum automatischen Ausfüllen von Passwörtern insgesamt deaktivieren kann, damit die Taste auf der Tastatur überhaupt nicht angezeigt wird und das allgemeine Verhalten dem vor iOS 11 entspricht.
textContentType
Eigenschaft des Felds für Benutzername und Kennwort auf.textContentType
- festzulegen. Dies sollte iOS 11 mitteilen, dass Ihre Felder keine Felder für Benutzername / Kennwort sind (obwohl dies der Fall ist), und verhindern, dass die Zubehöransicht angezeigt wird. So etwas wie "self.passwordField.textContentType = .textContentType"Antworten:
iOS 11 & 12 & 13 - Swift 4.2 & 5 (aktualisiert):
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: "") }
Erklärung zu iOS 11 :
Stellen Sie sicher, dass Sie alle Ihre
UITextField
Objekte so einrichten.Wenn Sie beispielsweise ein
UITextField
Objekt haben, bei dem der Benutzer seine E-Mail-Adresse eingeben muss, und ein anderes Objekt, bei dem der Benutzer sein Kennwort eingeben muss, weisen SieUITextContentType("")
beide Objekte zutextContentType
. Andernfalls funktioniert es nicht und die AutoFill-Zubehöransicht wird weiterhin angezeigt.quelle
UITextContentType
die heißtnewPassword
(siehe: developer.apple.com/documentation/uikit/uitextcontenttype/… ). Versuchen Sie, den Inhaltstyp für Kennworttextfelder auf diesen Typ festzulegen. Ich denke, iOS zeigt dann die AutoFill-Zubehöransicht nicht an, da der Benutzer gezwungen ist, ein neues Kennwort einzurichten und kein zuvor eingerichtetes Kennwort mithilfe der AutoFill-Zubehöransicht zu verwenden / darauf zuzugreifen. Im Moment ist dies nur Theorie. Ich bin nicht sicher, ob dies funktionieren wird, aber lassen Sie mich wissen, ob es funktioniert!UITextContentType
aufnewPassword
funktioniert nicht. Ich habe die Lösung von @GalShahar ausprobiert, aber es hat mir nicht gefallen. Stattdessen setze ich dasUITextContentType
aufoneTimeCode
. Das funktioniert jetzt.isSecureTextEntry
zu falschen zuerst zusätzlich zu SatzUITextContentType
zuoneTimeCode
. Wir können einstellenisSecureTextEntry
, was wir wollen, sobald sie das Textfeld eingeben..isSecureTextEntry
auf ,true
bevor SietextContentType
zu.oneTimeCode
und es funktioniert wie erwartet. Ich weiß nicht, wie Ihr Code aussieht, aber beim Initialisieren des Textfelds ist die Reihenfolge der Einrichtung seiner Eigenschaften nicht wichtig.iOS 12 scheint das Kennwort textFields auch nach
isSecureTextEntry
Eigenschaften und nicht nur nachtextContentType
Eigenschaften zu erkennen. Daher ist es nicht wirklich möglich, diese Zubehöransicht auszublenden, es sei denn, Sie setzen beide textContentType auf nichts und entfernen die SecureEntry-Funktion (und verursachen eine Sicherheitslücke in Ihrer App) verhindert dann, dass iOS 12 das textField als Kennwort textField erkennt und diese nervige Zubehöransicht anzeigt.In meinem Fall verursachte das Zubehör einen Fehler, der dazu führte, dass meine App beim Tippen nicht mehr reagierte (wodurch meine App auch im App-Überprüfungsprozess abgelehnt wurde). Also musste ich diese Funktion entfernen. Ich wollte dieses Sicherheitsmerkmal nicht aufgeben, also musste ich die Dinge selbst lösen.
Die Idee ist, die SecureEntry-Funktion zu entfernen, sie jedoch manuell hinzuzufügen. Es hat funktioniert:
Es kann so gemacht werden:
Schneller 4-Wege:
Zunächst, wie hier beantwortet,
textContentType
auf nichts gesetzt:if #available(iOS 10.0, *) { passwordText.textContentType = UITextContentType("") emailText.textContentType = UITextContentType("") }
Deklarieren Sie dann eine String-Variable, die später unseren textField-Realinhalt enthält:
var passwordValue = ""
Fügen Sie dem passwordTextField ein Ziel hinzu, das jedes Mal aufgerufen wird, wenn sich der textField-Inhalt ändert:
passwordText.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
Das ist es, was die Magie bewirkt. Deklarieren Sie die Funktion, die die Textersetzungen übernimmt:
@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) }
Stellen Sie schließlich textField's
autocorrectionType
auf ein.no
, um prädiktiven Text zu entfernen:Verwenden
passwordValue
Sie diese Option, um Ihre Anmeldung durchzuführen.Hoffe es wird jemandem helfen.
AKTUALISIEREN
Es fängt auch eingefügte Werte ab und hat vergessen, sie vorher hinzuzufügen.
quelle
Die Funktion kann deaktiviert werden, indem ein Inhaltstyp angegeben wird, der weder Benutzername noch Kennwort ist. Wenn der Benutzer beispielsweise eine E-Mail-Adresse eingeben soll, können Sie diese verwenden
quelle
Sie können eine Erweiterung für UITextContentType wie folgt hinzufügen
extension UITextContentType { public static let unspecified = UITextContentType("unspecified") }
Danach können Sie es verwenden
if #available(iOS 10.0, *) { passwordField.textContentType = .unspecified }
quelle
Ein sehr einfacher Ansatz in ios11 hat bei mir funktioniert. Angenommen, Ihre iboutlets sind usernametextfield und passwordtextfield. Verwenden Sie in der viewDidLoad () -Funktion Ihres Viewcontrollers, die beide Outlest enthält, den folgenden Code
usernametextfield.textContentType = UITextContentType("") passwordtextfield.textContentType = UITextContentType("")
Danach wird die Option zum automatischen Ausfüllen von Zubehör nicht mehr angezeigt, wenn Sie auf Ihre Textfelder tippen.
quelle
als Antwort auf @Gal Shahar Antwort.
iOS 12 erkennt Passwort textFields nach
isSecureTextEntry
Eigenschaft und nicht nur nachtextContentType
Eigenschaft.Umgehen, um den Vorschlag zum automatischen Ausfüllen zu umgehen.
isSecureTextEntry
Eigenschaft auf false.self.passwordTextField.secureTextEntry = NO;
isSecureTextEntry
Eigenschaft.- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField == self.passwordTextField && !self.passwordTextField.secureTextEntry) { self.passwordTextField.secureTextEntry = YES; } return YES; }
HINWEIS: - Verwenden Sie NICHT die
shouldBeginEditing
UITextField-Delegatmethode, da weiterhin Vorschläge zum automatischen Ausfüllen angezeigt werden. Verwenden Sie NICHT dietextFieldDidChange
UITextField-Delegatenmethode. Der erste Zeichner wird automatisch gelöscht, da dies nach der Anzeige des ersten Zeichens geschieht. Und 'SecureTextEntry' leert das Feld.quelle
Ziel c
if (@available(iOS 10, *)){ self.tfEmail.textContentType = @""; self.tfPassword.textContentType = @""; }
Das hat bei mir funktioniert.
quelle
Das automatische Ausfüllen ist für Benutzer standardmäßig aktiviert. iOS speichert alle Passwörter im Schlüsselbund und stellt sie in Ihren Apps über die Tastatur zur Verfügung.
UITextView
undUITextField
automatisch für das AutoFill-Passwort berücksichtigt. Sie können deaktivieren, indem Sie einen Inhaltstyp angeben, der weder Benutzername noch Kennwort ist. Wenn die Inhaltstypinformationen jedoch bereits im Schlüsselbund gespeichert sind, werden sie in der Schnellleiste angezeigt.UITextContentType
Daher ist es besser, einen leeren Typ zuzuweisen, und es wird keine Quickbar angezeigt.Beispiel:
if #available(iOS 10.0, *) { self.textField.textContentType = UITextContentType("") } else { // Fallback on earlier versions }
quelle
Dies funktionierte für iOS 12 und 10:
if (@available(iOS 10, *)) { passwordTextField.textContentType = UITextContentTypeStreetAddressLine2; } if (@available(iOS 12, *)) { passwordTextField.textContentType = UITextContentTypeOneTimeCode; }
quelle
Sie können die Kombination aus Benutzername und Kennwort "deaktivieren", indem Sie
textContentType
dem Kennworttextfeld einen Dummy zuweisen .passwordFormField.textContentType = UITextContentType("dummy")
Dadurch wurde das Schlüsselsymbol sowohl für das Kennwortfeld als auch für das vorangegangene E-Mail-Feld deaktiviert. Auf diese Weise verwenden Sie keinen der vordefinierten Werte und vermeiden, dass in der Tastaturzubehöransicht nicht verwandte Vorschläge angezeigt werden.
quelle
newPassword
UITextContentType. Ich weiß jedoch nicht, wie ich dieses neue Verhalten vermeiden soll.Ziel C-Version:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) { self.passwordTextField.textContentType = @""; self.confirmPasswordTextField.textContentType = @""; }
wo
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
quelle
Soweit ich weiß, funktioniert die Antwort von Bem in iOS 12 nicht und die Antwort von Gal Shahar berücksichtigt einige Randfälle nicht (z. B. wenn ein Benutzer mehrere Zeichen gleichzeitig löscht). Ich habe dies mit einer IBAction umgangen, sodass ich nicht mehr nach der iOS-Version suchen musste. Ich bin nur ein Anfänger, daher ist dies möglicherweise nicht die "beste" oder effizienteste Antwort, aber für mich war dies am sinnvollsten:
Deaktivieren Sie zunächst "Sichere Texteingabe" im Storyboard oder setzen Sie sie über den Code für Ihr Kennwort UITextField auf "false" / "NO". Dadurch wird verhindert, dass iOS versucht, automatisch zu füllen.
Verknüpfen Sie dann Ihr Passwort UITextField mit einer IBAction. Meins heißt:
Die von mir geschriebene IBAction-Funktion ermittelt die Unterschiede zwischen dem Startkennwort eines Benutzers und dem, was in das Kennwort UITextField eingegeben wurde, und erstellt anhand dieser Informationen ein neues Kennwort:
class Login: UIViewController { var password = "" override func viewDidLoad() { super.viewDidLoad() } @IBAction func editPasswordField(_ sender: UITextField) { var input = Array(sender.text ?? "") var oldPassword = Array(password) var newPassword = Array("") //if character(s) are simply deleted from "passwordField" (not replaced or added to), "cursorPosition" is used to determine which corresponding character(s) need to also be removed from "oldPassword" //this is indicated by "input" comprising of only "•" (bullets) and being shorter in length than "oldPassword" var onlyBullets = true for char in input { if char != "•" { onlyBullets = false } } if onlyBullets && input.count < oldPassword.count { if let selectedRange = sender.selectedTextRange { let cursorPosition = sender.offset(from: sender.beginningOfDocument, to: selectedRange.start) let prefix = String(oldPassword.prefix(cursorPosition)) let suffix = String(oldPassword.suffix(input.count - cursorPosition)) input = Array(prefix + suffix) } else { input = Array("") } } //if no changes were made via input, input would comprise solely of a number of bullets equal to the length of "oldPassword" //therefore, the number of changes made to "oldPassword" via "input" can be measured with "bulletDifference" by calculating the number of characters in "input" that are NOT bullets var bulletDifference = oldPassword.count for char in input { if char == "•" { bulletDifference -= 1 } } //the only way "bulletDifference" can be less than 0 is if a user copy-pasted a bullet into "input", which cannot be allowed because it breaks this function //if a user pastes bullet(s) into "input", "input" is deleted //an edge case not accounted for is pasting a mix of characters and bullets (i.e. "ex•mple") when "oldPassword.count" exceeds the number of bullets in the mixed input, but this does not cause crashes and therefore is not worth preventing if bulletDifference < 0 { bulletDifference = oldPassword.count input = Array("") } //"bulletDifference" is used to remove every character from "oldPassword" that corresponds with a character in "input" that has been changed //a changed character in "input" is indicated by the fact that it is not a bullet //once "bulletDifference" equals the number of bullets deleted, this loop ends var bulletsDeleted = 0 for i in 0..<input.count { if bulletsDeleted == bulletDifference { break } if input[i] != "•" { oldPassword.remove(at: i - bulletsDeleted) bulletsDeleted += 1 } } //what remains of "oldPassword" is used to substitute bullets in "input" for appropriate characters to create "newPassword" //for example, if "oldPassword" is "AcbDE" and "input" is "•bc••", then "oldPassword" will get truncated to "ADE" and "newPassword" will equal "A" + "bc" + "DE", or "AbcDE" var i = 0 for char in input { if char == "•" { newPassword.append(oldPassword[i]) i += 1 } else { newPassword.append(char) } } password = String(newPassword) //"passwordField.text" is then converted into a string of bullets equal to the length of the new password to ensure password security in the UI sender.text = String(repeating: "•", count: password.count) } }
Konstruktive Kritik wird geschätzt!
quelle
Sie können hier verschiedene Antworten ausprobieren , die zu dem Schluss führen, dass es wahrscheinlich möglich ist, die Zubehöransicht zu entfernen. Dies hinterlässt jedoch einige Fehler.
Sie könnten möglicherweise versuchen, eine benutzerdefinierte Tastatur nur für Kennwortfelder zu implementieren. Versuchen Sie auch, Vorschläge für Ihr Textfeld zu deaktivieren. Ich denke, das verbirgt auch das
accessoryView
.EDIT: Immer noch keine Antwort in Apple-Foren auf die gleiche Frage. Auch dazu konnte ich in der offiziellen
UITextField
Dokumentation nichts finden .quelle
Verrücktes Personal passiert in diesem Thema. Ich habe ohne iOS ein Passwort vorgeschlagen, mir aber eine automatische Ausfüllung nur für E-Mails gegeben. Nur wenn jemand es so braucht. Nach verschiedenen Kombinationen und verschiedenen Arten
textContentType
habe ich es gemacht, wie ich wollte.Und mit diesem Code hat es funktioniert. Es spielt keine Rolle, ob Sie haben
email
oderusername
es wird Ihnen einen Vorschlag mit dem machen, was Sie brauchen. Daher habe ich die automatische Ausfüllansicht für Zubehör deaktiviert und nur die automatische Ausfüllung in der Symbolleiste der Tastatur belassen.self.passwordField.isSecureTextEntry = true if #available(iOS 11.0, *) { self.emailField.textContentType = .username self.emailField.keyboardType = .emailAddress } if #available(iOS 12.0, *) { self.passwordField.textContentType = .password self.passwordField.keyboardType = .default }
quelle
self.passwordTextField.autocorrectionType = NO;
Es scheint nicht zu funktionieren, das Schlüsselbundzeichen ist noch da,
self.passwordTextField.textContentType = UITextContentTypeName;
Der obige Code funktioniert, aber wenn die Benutzer ihr Apple ID-Konto eingerichtet haben, wird der Name der Apple ID auf der Tastatur angezeigt. Sie können ihn nicht deaktivieren, indem Sie autocorrectionType auf No setzen. Sie sind sich nicht sicher, ob Apple diese Funktion zum automatischen Ausfüllen noch verfeinert Im Moment ist es ziemlich fehlerhaft.
quelle
Das hat bei mir funktioniert:
HINWEIS: Versuchen Sie, diesen Code in das Kennwort einzutragen, das Kennwort zu bestätigen (falls zutreffend) UND E-Mail-Textfelder. Ich habe es nicht in das E-Mail-Textfeld eingefügt und es wurde immer noch für die beiden Passwortfelder angezeigt.
if #available(iOS 12, *) { // iOS 12: Not the best solution, but it works. cell.textField.textContentType = .oneTimeCode } else { // iOS 11: Disables the autofill accessory view. cell.textField.textContentType = .init(rawValue: "") }
quelle
Ich denke, alle UITextField textContentType in Form zu setzen
UITextContentType("")
oder.oneTimeCode
ist keine saubere Lösung. Aktivieren / DeaktivierenisSecureTextEntry
gibt Ihnen immer noch das gleiche Problem.@Gal Shahars Antwort ist nett, aber immer noch nicht perfekt. Das maskierte Zeichen ist nicht dasselbe wie das maskierte Zeichen, das im sicheren Eingabetext von Apple verwendet wird. Es sollte das Unicode-Zeichen 'BLACK CIRCLE' (U + 25CF) https://www.fileformat.info/info/unicode/char/25cf/index.htm verwenden
Außerdem wird die Cursorbewegung nicht verarbeitet. Beim Einfügen von Text in die Mitte wird die Cursorposition an das Ende des Textes geändert. Beim Auswählen und Ersetzen von Text erhalten Sie den falschen Wert.
Wenn Sie sich für die Verwendung von benutzerdefiniertem isSecureEntryText entscheiden, um das automatische Ausfüllen des Kennworts zu vermeiden, lautet der folgende Code:
Swift 5 (einfache Version)
@IBOutlet weak var passwordTextField: UITextField! var maskedPasswordChar: String = "●" var passwordText: String = "" var isSecureTextEntry: Bool = true { didSet { let selectedTextRange = passwordTextField.selectedTextRange passwordTextField.text = isSecureTextEntry ? String(repeating: maskedPasswordChar, count: passwordText.count) : passwordText passwordTextField.selectedTextRange = selectedTextRange } } //this is UITextFieldDelegate func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == passwordTextField { //update password string if let swiftRange = Range(range, in: passwordText) { passwordText = passwordText.replacingCharacters(in: swiftRange, with: string) } else { passwordText = string } //replace textField text with masked password char textField.text = isSecureTextEntry ? String(repeating: maskedPasswordChar, count: passwordText.count) : passwordText //handle cursor movement if let newPosition = textField.position(from: textField.beginningOfDocument, offset: range.location + string.utf16.count) { textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition) } return false } return true }
Swift 5 (KOMPLETTE Version mit Sicherung der letzten Zeichenanimation)
private struct Constants { static let SecuringLastCharPasswordDelay = 1.5 } @IBOutlet weak var passwordTextField: UITextField! private var secureTextAnimationQueue: [String] = [] var maskedPasswordChar: String = "●" var passwordText: String = "" var isSecureTextEntry: Bool = true { didSet { secureTextAnimationQueue.removeAll() let selectedTextRange = passwordTextField.selectedTextRange passwordTextField.text = isSecureTextEntry ? String(repeating: maskedPasswordChar, count: passwordText.count) : passwordText passwordTextField.selectedTextRange = selectedTextRange } } //this is UITextFieldDelegate func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField == passwordTextField { //update password string if let swiftRange = Range(range, in: passwordText) { passwordText = passwordText.replacingCharacters(in: swiftRange, with: string) } else { passwordText = string } //replace textField text with masked password char updateTextFieldString(textField, shouldChangeCharactersIn: range, replacementString: string) //handle cursor movement if let newPosition = textField.position(from: textField.beginningOfDocument, offset: range.location + string.utf16.count) { textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition) } return false } return true } private func updateTextFieldString(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) { if isSecureTextEntry { if string.count == .one, let text = textField.text { let maskedText = String(repeating: maskedPasswordChar, count: text.count) var newMaskedText = String() if let swiftRange = Range(range, in: maskedText) { newMaskedText = maskedText.replacingCharacters(in: swiftRange, with: string) } else { newMaskedText = text + maskedText } textField.text = newMaskedText secureTextAnimationQueue.append(string) asyncWorker.asyncAfter(deadline: .now() + Constants.SecuringLastCharPasswordDelay) { [weak self] in self?.securingLastPasswordChar() } } else { secureTextAnimationQueue.removeAll() textField.text = String(repeating: maskedPasswordChar, count: passwordText.count) } } else { textField.text = passwordText } } private func securingLastPasswordChar() { guard secureTextAnimationQueue.count > .zero, isSecureTextEntry else { return } secureTextAnimationQueue.removeFirst() if secureTextAnimationQueue.count == .zero { let selectedTextRange = passwordTextField.selectedTextRange passwordTextField.text = String(repeating: maskedPasswordChar, count: passwordText.count) passwordTextField.selectedTextRange = selectedTextRange } }
quelle
Ich habe den Screenshot angehängt. Sie können den Inhaltstyp als Benutzername im Storyboard ändern oder programmgesteuert. Sie können eine Erweiterung für UITextfield erstellen.
func diableAutofill() { self.autocorrectionType = .no if #available(iOS 11.0, *) { self.textContentType = .username } else { self.textContentType = .init("") } }
quelle
Dank Apple konnte ich mit nativen Methoden keinen Weg finden, als isSecureTextEntry auf YES gesetzt wurde. Der Weg von Gal Shahar ist die einzige Lösung zum Deaktivieren der Option zum automatischen Ausfüllen von Passwörtern. Aber es ist einfacher damit
Ziel c
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
schnell
textField(_:shouldChangeCharactersIn:replacementString:)
delegieren. Und verwenden Sie einfachen Code wie diesen. Deklarieren Sie eine String-Variable, die später unseren echten textField-Inhalt enthält. Meiner ist pswd.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { //Thanks iOS13!!! if(!_pswd) { _pswd = @""; } _pswd = [_pswd stringByReplacingCharactersInRange:range withString:string]; if (!buttonShowPassword.selected) { textField.text = [@"" stringByPaddingToLength:_pswd.length withString: @"•" startingAtIndex:0]; } else { textField.text = _pswd; } return NO; }
quelle