Получить полную строку в iOS8 Custom Keyboard Extension
Я создаю Custom Keyboard Extension для iOS 8.
Я хочу получить всю строку, которую пользователь написал в поле ввода текста.
К сожалению, я сталкиваюсь с двумя основными проблемами:
1) Я получаю ноль в этом обратном вызове:
- (void)textDidChange:(id<UITextInput>)textInput
2) Я получаю только частичную строку, когда я вызываю эти методы:
- [self.textDocumentProxy documentContextAfterInput];
- [self.textDocumentProxy documentContextBeforeInput];
Я хочу получить всю строку в текстовом вводе, который в данный момент редактирует пользователь. Что вы предлагаете мне сделать?
Спасибо!
5 ответов
Я нашел как.
- (void)doSomething{
dispatch_async(inputQueue, ^{
[self getAllString];
});
return;
}
Сначала оберните ваш метод с помощью dispatch_async и вашей собственной очереди.
#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];
}
Есть две утилиты:
@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
а также
-(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;
}
ВЫ ДОЛЖНЫ БЕСПОКОЙСТВОВАТЬ ДЛЯ КАЖДОГО ПРОКСИ-МЕТОДА.
результат:
Текстовое окно
012, 345! 6789
0123. 4567! 89012 '34567890.' 123456789
Приставка
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
Я столкнулся с той же проблемой со строками documentContextAfterInput и documentContextBeforeInput. Я думаю, что IOS8 возвращает только несколько символов по обе стороны от точки вставки. Я думаю, что это намеренно.
У вас всегда может быть изменяемый массив, в котором вы сохраняете весь напечатанный текст, и удаляете последний символ при удалении (или, возможно, делаете какое-то обнаружение с documentContextAfterInput/BeforeInput, чтобы найти место для удаления текста, а затем удалить эту часть). Это сложнее, чем просто вызывать метод giveMeWholeString, но он будет работать в большинстве случаев, особенно если они вводят и удаляют только с помощью клавиши удаления.
У меня была такая же проблема, и я думаю, что она была исправлена с Xcode 6 beta 4.
Просто добавьте documentContextAfterInput к documentContextBeforeInput, чтобы получить полный текст поля ввода.
В Xcode 6.1 кажется, что documentContextBeforeInput возвращает частичную строку только в симуляторе и отлично работает на устройстве.
Изменить: хорошо, ребята, вот мой код:
-(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);
}
и вывод (только на устройстве): 2014-11-16 12:32:42.708 Клавиатура [2228:393159] Спасибо! Howareyou?