UITextDocumentProxy adjustTextPositionByCharacterOffset 问题
UITextDocumentProxy adjustTextPositionByCharacterOffset Issue
我正在使用 Swift 为 iOS 8 开发自定义键盘。我正在尝试编写一个在光标两侧插入文本的函数。
我在我的 class 中定义了这个继承自 UIInputViewController
的函数
func nestedTag(tag: NSString) {
let proxy = self.textDocumentProxy as UITextDocumentProxy
proxy.insertText(tag)
proxy.insertText(tag)
proxy.insertText(" ")
proxy.adjustTextPositionByCharacterOffset(-1 * (1 + tag.length))
例如,如果我用 !!!
调用 nestedTag
,我希望得到键盘输入的文本字段:
!!!<CURSOR>!!!<SPACE>
问题是,如果我在没有输入的情况下专注于空文本字段时调用此函数,则会得到错误的结果。
!!!!!!<SPACE><CURSOR>
此外,如果我在关注填充的文本字段时调用此函数,我会得到不同的错误行为。
前面的文本字段:
helloworld
后面的文本字段:
hello w!!!!!! orld
在此示例中,光标确实向左移动了 4 个字符,但是这看起来好像对 adjustTextPositionByCharacterOffset
的调用是在 对 [ 的三个调用之前调用的=19=] 尽管事实并非如此(见代码)。
两个 UITextDocumentProxy
方法的 documentation 似乎非常简单且不言自明,而且我似乎没有看到其他在线人遇到过这个问题。我似乎无法弄清楚我做错了什么以获得这些奇怪的结果。谢谢你的时间。
我正在苦苦挣扎,但我几乎没有发现,所以我分享它
textDocumentProxy 提供了 6 个方法
(insert
, move cursor
, delete
, afterInput
, beforeInput
, hasText
)
这 6 个方法和异步方法一样需要一些时间。
(每种方法需要不同的时间)
例如)原始序列:move insert move
-> 结果:insert move move
所以,我尝试在调用每个方法之前等待一段时间。
用 semaphore
和 dispatch_async
以及 dispatch_after
包装每个方法,
我们可以像同步方法一样等待它们。
inputQueue = dispatch_queue_create("happynewyear", 0);
inputQueue2 = dispatch_queue_create("happynewyear2", 0);
-(void)moveCursor:(NSInteger)num{
dispatch_async(inputQueue2, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_after(delay(TIME_INTERVAL), inputQueue, ^{
[self.textDocumentProxy adjustTextPositionByCharacterOffset:num];
NSLog(@"moveCursor : %ld",(long)num);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
-(void)insertText:(NSString*)string{
dispatch_async(inputQueue2, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_after(delay(TIME_INTERVAL), inputQueue, ^{
[self.textDocumentProxy insertText:string];
NSLog(@"insertText : %@",string);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
-(void)deleteBackward:(NSInteger)num{
dispatch_async(inputQueue2, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_after(delay(TIME_INTERVAL), inputQueue, ^{
for (int i = 0; i<num; ++i) {
[self.textDocumentProxy deleteBackward];
}
NSLog(@"deleteBackward : %ld",(long)num);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
延迟函数...
inline static dispatch_time_t delay(double delay){
return dispatch_time(
DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC
);
}
我用 TIME_INTERVAL
作为 0.01
这个技巧让你的代码保持顺序。
我正在尝试其他方法(afterInput、beforeInput ...),如上,
如果我解决了,我会回来
swift:
let TIME_INTERVAL: DispatchTime = DispatchTime.init(uptimeNanoseconds: UInt64(0.01))
let inputQueue = DispatchQueue(label: "input")
let inputQueue2 = DispatchQueue(label: "input2")
func deleteBackWard(num:NSInteger) -> Void {
self.inputQueue2.async {
let sema = DispatchSemaphore.init(value: 0)
self.inputQueue.asyncAfter(deadline: self.TIME_INTERVAL) {
for _ in 0...num {
self.textDocumentProxy.deleteBackward()
}
sema.signal()
}
sema.wait(timeout: DispatchTime.distantFuture)
}
}
func insertTextAsync(text: String) -> Void {
self.inputQueue2.async {
let sema = DispatchSemaphore.init(value: 0)
self.inputQueue.asyncAfter(deadline: self.TIME_INTERVAL) {
self.textDocumentProxy.insertText(text)
sema.signal()
}
sema.wait(timeout: DispatchTime.distantFuture)
}
}
func moveCursor(num:NSInteger) -> Void {
self.inputQueue2.async {
let sema = DispatchSemaphore.init(value: 0)
self.inputQueue.asyncAfter(deadline: self.TIME_INTERVAL) {
self.textDocumentProxy.adjustTextPosition(byCharacterOffset: num)
sema.signal()
}
sema.wait(timeout: DispatchTime.distantFuture)
}
}
第 Jeonghan Joo
我正在使用 Swift 为 iOS 8 开发自定义键盘。我正在尝试编写一个在光标两侧插入文本的函数。
我在我的 class 中定义了这个继承自 UIInputViewController
func nestedTag(tag: NSString) {
let proxy = self.textDocumentProxy as UITextDocumentProxy
proxy.insertText(tag)
proxy.insertText(tag)
proxy.insertText(" ")
proxy.adjustTextPositionByCharacterOffset(-1 * (1 + tag.length))
例如,如果我用 !!!
调用 nestedTag
,我希望得到键盘输入的文本字段:
!!!<CURSOR>!!!<SPACE>
问题是,如果我在没有输入的情况下专注于空文本字段时调用此函数,则会得到错误的结果。
!!!!!!<SPACE><CURSOR>
此外,如果我在关注填充的文本字段时调用此函数,我会得到不同的错误行为。
前面的文本字段:
helloworld
后面的文本字段:
hello w!!!!!! orld
在此示例中,光标确实向左移动了 4 个字符,但是这看起来好像对 adjustTextPositionByCharacterOffset
的调用是在 对 [ 的三个调用之前调用的=19=] 尽管事实并非如此(见代码)。
两个 UITextDocumentProxy
方法的 documentation 似乎非常简单且不言自明,而且我似乎没有看到其他在线人遇到过这个问题。我似乎无法弄清楚我做错了什么以获得这些奇怪的结果。谢谢你的时间。
我正在苦苦挣扎,但我几乎没有发现,所以我分享它
textDocumentProxy 提供了 6 个方法
(insert
, move cursor
, delete
, afterInput
, beforeInput
, hasText
)
这 6 个方法和异步方法一样需要一些时间。
(每种方法需要不同的时间)
例如)原始序列:move insert move
-> 结果:insert move move
所以,我尝试在调用每个方法之前等待一段时间。
用 semaphore
和 dispatch_async
以及 dispatch_after
包装每个方法,
我们可以像同步方法一样等待它们。
inputQueue = dispatch_queue_create("happynewyear", 0);
inputQueue2 = dispatch_queue_create("happynewyear2", 0);
-(void)moveCursor:(NSInteger)num{
dispatch_async(inputQueue2, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_after(delay(TIME_INTERVAL), inputQueue, ^{
[self.textDocumentProxy adjustTextPositionByCharacterOffset:num];
NSLog(@"moveCursor : %ld",(long)num);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
-(void)insertText:(NSString*)string{
dispatch_async(inputQueue2, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_after(delay(TIME_INTERVAL), inputQueue, ^{
[self.textDocumentProxy insertText:string];
NSLog(@"insertText : %@",string);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
-(void)deleteBackward:(NSInteger)num{
dispatch_async(inputQueue2, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_after(delay(TIME_INTERVAL), inputQueue, ^{
for (int i = 0; i<num; ++i) {
[self.textDocumentProxy deleteBackward];
}
NSLog(@"deleteBackward : %ld",(long)num);
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
}
延迟函数...
inline static dispatch_time_t delay(double delay){
return dispatch_time(
DISPATCH_TIME_NOW,
delay * NSEC_PER_SEC
);
}
我用 TIME_INTERVAL
作为 0.01
这个技巧让你的代码保持顺序。
我正在尝试其他方法(afterInput、beforeInput ...),如上,
如果我解决了,我会回来
swift:
let TIME_INTERVAL: DispatchTime = DispatchTime.init(uptimeNanoseconds: UInt64(0.01))
let inputQueue = DispatchQueue(label: "input")
let inputQueue2 = DispatchQueue(label: "input2")
func deleteBackWard(num:NSInteger) -> Void {
self.inputQueue2.async {
let sema = DispatchSemaphore.init(value: 0)
self.inputQueue.asyncAfter(deadline: self.TIME_INTERVAL) {
for _ in 0...num {
self.textDocumentProxy.deleteBackward()
}
sema.signal()
}
sema.wait(timeout: DispatchTime.distantFuture)
}
}
func insertTextAsync(text: String) -> Void {
self.inputQueue2.async {
let sema = DispatchSemaphore.init(value: 0)
self.inputQueue.asyncAfter(deadline: self.TIME_INTERVAL) {
self.textDocumentProxy.insertText(text)
sema.signal()
}
sema.wait(timeout: DispatchTime.distantFuture)
}
}
func moveCursor(num:NSInteger) -> Void {
self.inputQueue2.async {
let sema = DispatchSemaphore.init(value: 0)
self.inputQueue.asyncAfter(deadline: self.TIME_INTERVAL) {
self.textDocumentProxy.adjustTextPosition(byCharacterOffset: num)
sema.signal()
}
sema.wait(timeout: DispatchTime.distantFuture)
}
}
第 Jeonghan Joo