ios objective-c keyboard ios8

¿Cómo utilizar la autocorrección y la lista de accesos directos en el teclado personalizado iOS8?



objective-c keyboard (9)

Aunque no he intentado crear un teclado personalizado, estoy basando esta respuesta en lo que puedo ver en la documentación.

En su teclado, cree una propiedad llamada entries de tipo [AnyObject] (Array of AnyObjects).

En su método de init , o donde crea el teclado, llame a este método:

requestSupplementaryLexiconWithCompletion(completionHandler: { lexicon in self.entries = lexicon.entries })

Sospecho que las entries son en realidad una matriz de Strings o NSStrings, pero podría ser un diccionario o algún otro tipo. Al probar esto, intente averiguar qué tipo está realmente contenido en las entries antes de averiguar su lógica.

No creo que haya una manera de obtener las opciones de autocorrección predeterminadas de Apple actualmente. Sin embargo, esta charla sobre WWDC da una idea de cómo hicieron el trabajo de autocorrección en el iPhone OS original (alrededor de la marca de 30 minutos).

Menciona el uso de una búsqueda binaria de la matriz, lo que me lleva a creer que esta matriz está ordenada. Por supuesto, mucho podría haber cambiado desde que salió el primer iPhone ...

¡Buena suerte al descubrir esta nueva API!

Quiero usar la lista de autocorrección y acceso directo como el teclado inglés predeterminado con mi teclado personalizado. Reviso el documento del teclado pero no sé cómo usarlo.

En la documentación del teclado .

Cada teclado personalizado (independientemente del valor de su clave RequestsOpenAccess) tiene acceso a un léxico de autocorrección básico a través de la clase UILexicon. Utilice esta clase, junto con un léxico de su propio diseño, para proporcionar sugerencias y autocorrecciones a medida que los usuarios ingresan texto. El objeto UILexicon contiene palabras de varias fuentes, incluyendo:

  • Nombres y apellidos no pareados de la base de datos de la libreta de direcciones del usuario
  • Accesos directos de texto definidos en Configuración> General> Teclado> Lista de accesos directos
  • Un diccionario de palabras comunes.

¿Cómo acceder a la lista de accesos directos y la entrada de nuestro diccionario en Objective-C?

¿Cómo usar UILexicon con requestSupplementaryLexiconWithCompletion?


Cada teclado personalizado (independientemente del valor de su clave RequestsOpenAccess) tiene acceso a un léxico de autocorrección básico a través de la clase UILexicon . Utilice esta clase, junto con un léxico de su propio diseño, para proporcionar sugerencias y autocorrecciones a medida que los usuarios ingresan texto. El objeto UILexicon contiene palabras de varias fuentes, incluyendo:

Nombres y apellidos no pareados de la base de datos de la libreta de direcciones del usuario. Accesos directos de texto definidos en Configuración> General> Teclado> Lista de accesos directos.


Con respecto a la autocorrección, pude agregarlo mediante el link . Aquí está el fragmento de código que usé desde el enlace:

UITextChecker *checker = [[UITextChecker alloc] init]; NSRange checkRange = NSMakeRange(0, self.txView.text.length); NSRange misspelledRange = [checker rangeOfMisspelledWordInString:self.txView.text range:checkRange startingAt:checkRange.location wrap:NO language:@"en_US"]; NSArray *arrGuessed = [checker guessesForWordRange:misspelledRange inString:self.txView.text language:@"en_US"]; self.txView.text = [self.txView.text stringByReplacingCharactersInRange:misspelledRange withString:[arrGuessed objectAtIndex:0]];

La documentación completa de Apple se puede encontrar here .


En caso de que alguien todavía esté investigando esto, encontré una muy buena biblioteca de texto predictivo de C ++ llamada Presage . Parece hacer un buen trabajo basado en la demo, pero tengo muchos problemas para integrarlo como una biblioteca (vea mi pregunta here ).

¡Avíseme si alguien tiene alguna idea, muy interesado en hacer que esto funcione!


En realidad, UILexicon es solo una forma de obtener algunas palabras específicas del usuario que su sistema de corrección ortográfica no debe intentar arreglar. Probablemente, la forma más común de usarlo es completar la lista de palabras ignoradas de UITextChecker .

let lexicon: UILexicon = ... let checker: UITextChecker = ... for entry in lexicon.entries { if entry.documentText == entry.userInput { checker.ignoreWord(entry.documentText) } }

Además, UILexicon se puede usar como fuente de accesos directos auto-colocados como ("omw" = "¡A mi manera!"), Pero no es una corrección automática en términos de ortografía.


Esta es la forma en que puedes acceder a las palabras Lexicon:

[self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) { self.lexicon = receivedLexicon; for (UILexiconEntry *word in self.lexicon.entries) { // Text to be inserted into a text input object by a custom keyboard, corresponding to the userInput value in the same lexicon entry. NSLog(@"%@",word.documentText); // Text to match, during user input, to provide appropriate output to a text document from the documentText value in the same lexicon entry. NSLog(@"%@",word.userInput); } }];


Implementar el léxico se vería muy parecido a esto:

  1. Use requestSupplementaryLexiconWithCompletion() para obtener el léxico al iniciarse una vez.
  2. Cada texto de tipo se NSString se agrega a un NSString (seguimiento de la palabra actual)
  3. Cuando el usuario presiona espacio (final de la palabra actual), compruebe la cadena contra el léxico
  4. Si es una coincidencia, cuente el número de caracteres y elimine ese número de caracteres
  5. Introduzca la sugerencia sugerida por el léxico.
  6. Borrar la cadena y comenzar de nuevo

Además, también puede utilizar UITextChecker para ofrecer funciones de corrección automática más avanzadas.

Código (en Objective-C, esto puede no ser 100% exacto que escribí en SO mientras estaba en el bus, pero debería hacerlo):

UILexicon *lexicon; NSString *currentString; -(void)viewDidLoad { [self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) { self.lexicon = receivedLexicon; }]; } -(IBAction)myTypingAction:(UIButton *)sender { [documentProxy insertText:sender.title]; [currentString stringByAppendingString:sender.title]; } -(IBAction)space { [documentProxy insertText:@" "]; for (UILexiconEntry *lexiconEntry in lexicon.entries) { if (lexiconEntry.userInput isEqualToString:currentString) { for (int i = 0; currentString.length >=i ; i++) { [documentProxy deleteTextBackwards]; } [documentProxy insertText:lexiconEntry.documentText]; currentString = @""; } } }

No dude en comentar si tiene más preguntas.

Fuente: Experiencia personal con teclados iOS 8 y UILexicon


Puede usar la lógica de abajo para Autocorrección y también funcionará en iOS 10

-(void)didClickAtAlphaNumericKeyboardKey:(NSString *)value { if ([value isEqualToString:@" "]) { UITextChecker *checker = [[UITextChecker alloc] init]; currentString = self.textDocumentProxy.documentContextBeforeInput; NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSArray *components = [currentString componentsSeparatedByCharactersInSet:charSet]; NSString *lastWord = components.lastObject; NSRange checkRange = NSMakeRange(0, lastWord.length); NSRange misspelledRange = [checker rangeOfMisspelledWordInString:lastWord range:checkRange startingAt:checkRange.location wrap:NO language:@"en_US"]; NSArray *guessedWord = [checker guessesForWordRange:misspelledRange inString:lastWord language:@"en_US"]; if (guessedWord && guessedWord.count > 0) { for (int i = 0; lastWord.length >i ; i++) { [self.textDocumentProxy deleteBackward]; } [self.textDocumentProxy insertText:[guessedWord objectAtIndex:0]]; } } [self.textDocumentProxy insertText:value]; }


Rachits responde arriba en swift 4. Funciona con iOS 12

Tengo este ayudante para verificar si la cadena actual a ser probada por UITextChecker no es un espacio

func validate(string: String?) -> Bool { guard let text = string, !text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty else { return false } return true }

El verificador de texto está entonces en mi "Barra espaciadora", "Barra espaciadora, doble toque" y "Retorno". El siguiente ejemplo está en mi método "Espacio"

let textChecker = UITextChecker() let currentString = self.textDocumentProxy.documentContextBeforeInput if validate(string: currentString) { let charSet = NSCharacterSet.whitespacesAndNewlines let components = currentString?.components(separatedBy: charSet) let lastWord = components?.last let checkRange = NSMakeRange(0, lastWord?.count ?? 0) let misspelledRange = textChecker.rangeOfMisspelledWord(in: lastWord!, range: checkRange, startingAt: checkRange.location, wrap: false, language: "en_US") if misspelledRange.length != 0 { let guessedWord: Array = textChecker.guesses(forWordRange: misspelledRange, in: lastWord!, language: "en_US")! if guessedWord.count > 0 { var i = 0 while (lastWord?.length)! > i { textDocumentProxy.deleteBackward() i += 1 } self.textDocumentProxy.insertText(guessedWord[0]) } } } self.textDocumentProxy.insertText(" ")

Tuve que hacer dos cambios al código de Rachits. Primero para validar la cadena actual, ya que lanza una excepción si presiona la barra espaciadora dos veces. Y segundo, para verificar si el rango mal escrito no es 0 porque eso también estaba lanzando una excepción que todavía no he descubierto por qué. Pero esto funciona para mí ahora como es.