16

我正在为 iOS 8 创建自定义键盘扩展。

我想获取用户在文本输入字段中编写的整个字符串。

不幸的是,我偶然发现了两个主要问题:

1)我在这个回调中得到 null :

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

2)当我调用这些方法时,我只得到部分字符串:

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

我想在用户当前正在编辑的文本输入中获取整个字符串你建议我做什么?

谢谢!

4

5 回答 5

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
于 2015-03-18T12:03:33.330 回答
3

我在 documentContextAfterInput 和 documentContextBeforeInput 字符串中遇到了同样的问题。我认为 IOS8 只返回插入点两侧的少数字符。我认为这是故意的。

于 2014-07-23T05:10:40.700 回答
2

您总是可以有一个可变数组来存储所有键入的文本,并在删除时删除最后一个字符(或者可能使用 documentContextAfterInput/BeforeInput 进行一些检测以找到删除文本的位置,然后删除该部分)。这比仅仅调用“giveMeWholeString”方法更复杂,但它适用于大多数情况,特别是如果他们只是用删除键键入和删除。

于 2014-07-27T07:45:10.593 回答
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 Keyboard[2228:393159]Thanks!howareyou?

于 2014-11-13T09:15:09.100 回答
-1

我遇到了同样的问题,我认为 Xcode 6 beta 4 已经解决了这个问题。

只需将 documentContextAfterInput 附加到 documentContextBeforeInput 即可获得完整的输入字段文本。

于 2014-07-29T15:49:13.043 回答