我正在为iOS 8创建自定义键盘扩展程序。
我想获取用户在文本输入字段中写的整个字符串。
不幸的是,我偶然发现了两个主要问题:
1)我在这个回调中得到null:
- (void)textDidChange:(id<UITextInput>)textInput
2)当我调用这些方法时,我只得到部分字符串:
- [self.textDocumentProxy documentContextAfterInput];
- [self.textDocumentProxy documentContextBeforeInput];
我想在用户当前正在编辑的文本输入中获取整个字符串 你有什么建议我做的?
谢谢!
答案 0 :(得分:6)
我找到了如何。
- (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
答案 1 :(得分:3)
我遇到了与documentContextAfterInput和documentContextBeforeInput字符串相同的问题。我认为IOS8只返回插入点两侧的少数几个字符。我认为这是故意的。
答案 2 :(得分:2)
您可以随时使用可变数组存储所有键入的文本,并在删除时删除最后一个字符(或者使用documentContextAfterInput / BeforeInput进行一些检测以找到要删除文本的位置,然后删除该部分)。这比调用'giveMeWholeString'方法更复杂,但它适用于大多数情况,特别是如果他们只使用删除键进行输入和删除。
答案 3 :(得分:0)
我遇到了同样的问题,我认为已经使用Xcode 6 beta 4进行了修复。
只需将documentContextAfterInput附加到documentContextBeforeInput即可获取完整的输入字段文本。
答案 4 :(得分:0)
在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?