ios8 ios-app-extension uiinputviewcontroller

Obtén una cadena completa en la extensión del teclado personalizado iOS8



ios-app-extension uiinputviewcontroller (5)

Estoy creando una extensión de teclado personalizado para iOS 8.

Quiero obtener toda la cadena que el usuario escribió en el campo de entrada de texto.

Desafortunadamente me tropiezo con dos problemas principales:

1) Tengo nulo en esta devolución de llamada:

- (void)textDidChange:(id<UITextInput>)textInput

2) Solo obtengo String parcial Cuando llamo a estos métodos:

- [self.textDocumentProxy documentContextAfterInput]; - [self.textDocumentProxy documentContextBeforeInput];

Quiero obtener la cadena completa en la entrada de texto que el usuario está editando. ¿Qué sugieres que haga?

¡Gracias!


Encontré Cómo.

- (void)doSomething{ dispatch_async(inputQueue, ^{ [self getAllString]; }); return; }

Primero envuelva su método con dispatch_async y su propia cola.

#define DELAY_LENGTH 0.01 -(void)getAllString{ id<UITextDocumentProxy> proxy = self.textDocumentProxy; NSString* before = [proxy documentContextBeforeInput]; NSString* after = [proxy documentContextAfterInput]; NSMutableArray* afterArray = [NSMutableArray arrayWithCapacity:10]; while (after) { unsigned long afterLength = [after length]; if(afterLength <= 0){ break; } [afterArray addObject:after]; [NSThread sleepForTimeInterval:DELAY_LENGTH]; [proxy adjustTextPositionByCharacterOffset:afterLength]; [NSThread sleepForTimeInterval:DELAY_LENGTH]; after = [proxy documentContextAfterInput]; } NSMutableArray* beforeArray = [NSMutableArray arrayWithCapacity:10]; [NSThread sleepForTimeInterval:DELAY_LENGTH]; before = [proxy documentContextBeforeInput]; while (before) { unsigned long beforeLength = [before length]; if (beforeLength <= 0) { break; } [beforeArray addObject:before]; [NSThread sleepForTimeInterval:DELAY_LENGTH]; [proxy adjustTextPositionByCharacterOffset:-beforeLength]; [NSThread sleepForTimeInterval:DELAY_LENGTH]; before = [proxy documentContextBeforeInput]; } NSLog(@"afterArray: %@",[self getArrayString:afterArray reverse:false]); NSString* beforeString = [self getArrayString:beforeArray reverse:true]; NSLog(@"beforArray: %@",beforeString); [NSThread sleepForTimeInterval:DELAY_LENGTH]; [proxy adjustTextPositionByCharacterOffset:beforeString.length]; }

Hay dos utils:

@implementation NSArray (Reverse) - (NSArray *)reversedArray { NSMutableArray *array = [NSMutableArray arrayWithCapacity:[self count]]; NSEnumerator *enumerator = [self reverseObjectEnumerator]; for (id element in enumerator) { [array addObject:element]; } return array; } @end

y

-(NSString*)getArrayString : (NSArray*)array reverse : (BOOL)isReverse{ NSArray* tar = isReverse ? [array reversedArray] : array; NSMutableString* result = [NSMutableString stringWithCapacity:10]; for (NSString* string in tar) { [result appendString:string]; } return result; }

USTED TIENE QUE DORMIR UN POCO POR CADA MÉTODO DE PROXY.

resultado:

Caja de texto

012, 345! 6789 0123. 4567! 89012 ''34567890.'' 123456789

Consola

2015-03-18 21:04:15.034 moveCursor[39413:2692914] afterArray: 2015-03-18 21:04:15.035 moveCursor[39413:2692914] beforArray: 012, 345! 6789 0123. 4567! 89012 ''34567890.'' 123456789


Me encontré con el mismo problema con las cadenas documentContextAfterInput y documentContextBeforeInput. Creo que IOS8 solo devuelve un puñado de caracteres a cada lado del punto de inserción. Creo que esto es intencional.


Siempre se puede tener una matriz mutable en la que se almacena todo el texto escrito, y se elimina el último carácter al eliminar (o tal vez hacer alguna detección con documentContextAfterInput / BeforeInput para encontrar el lugar para eliminar el texto y luego eliminar esa parte). Esto es más complicado que solo llamar a un método ''giveMeWholeString'', pero funcionaría en la mayoría de los casos, especialmente si solo estuvieran escribiendo y eliminando con la tecla eliminar.


Tuve el mismo problema y creo que se ha solucionado con Xcode 6 beta 4.

Simplemente agregue documentContextAfterInput a documentContextBeforeInput para obtener el texto completo del campo de entrada.


en Xcode 6.1 parece que documentContextBeforeInput devuelve una cadena parcial solo en el simulador y funciona bien en el dispositivo.

Edit: ok chicos aquí está mi código:

-(void)addPeriod{ if (![self endsWithCharacter:''.'' String:[[((UIInputViewController*)self.delegate).textDocumentProxy documentContextBeforeInput] stringByReplacingOccurrencesOfString:@" " withString:@""]]) { [((UIInputViewController*)self.delegate).textDocumentProxy deleteBackward]; [((UIInputViewController*)self.delegate).textDocumentProxy insertText:@"."]; } } - (BOOL) endsWithCharacter: (unichar) c String:(NSString*)str { NSLog(@"%@",str); NSUInteger length = [str length]; return (length > 0) && ([str characterAtIndex: length - 1] == c); }

y la salida (solo en el dispositivo) es: 2014-11-16 12: 32: 42.708 Teclado [2228: 393159] ¡Gracias! ¿Cómo está?