如何在iOS8自定义键盘中使用自动更正和快捷键列表?

时间:2021-03-14 07:11:19

I want to use the autocorrection and shortcut list like default English keyboard with my custom keyboard. I check the in keyboard document but don't know how to use it.

我想用我的自定义键盘使用自动纠错和快捷键列表,比如默认的英语键盘。我检查了一下键盘文件,但不知道怎么用。

In keyboard documentation.

在键盘的文档。

Every custom keyboard (independent of the value of its RequestsOpenAccess key) has access to a basic autocorrection lexicon through the UILexicon class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text. The UILexicon object contains words from various sources, including:

每个自定义键盘(独立于其RequestsOpenAccess键的值)都可以通过UILexicon类访问一个基本的自动修正词汇。利用这个类,以及您自己设计的词典,在用户输入文本时提供建议和自动更正。UILexicon对象包含来自各种来源的词,包括:

  • Unpaired first names and last names from the user’s Address Book database
  • 用户地址簿中未配对的名和姓
  • Text shortcuts defined in the Settings > General > Keyboard > Shortcuts list
  • 文本快捷键定义在设置>一般>键盘>快捷键列表
  • A common words dictionary
  • 一个常用单词字典

How to access shortcut list and input from our dictionary in Objective-C?

如何在Objective-C中访问字典中的快捷列表和输入?

How to use UILexicon with requestSupplementaryLexiconWithCompletion?

如何将UILexicon与requestementarylexiconwithcompletion一起使用?

8 个解决方案

#1


22  

Implementing the lexicon would look pretty much like this:

实现lexicon的方式大致如下:

  1. Use requestSupplementaryLexiconWithCompletion() to get the lexicon upon launch once.
  2. 使用requestSupplementaryLexiconWithCompletion()在启动时获取lexicon。
  3. Each type text is inputted add it to a NSString (tracking the current word)
  4. 输入的每个类型文本都将其添加到NSString(跟踪当前单词)
  5. When user presses space (end of curent word) check the string against the lexicon
  6. 当用户按空格(curent word结尾)时,根据字典检查字符串
  7. If it's a match count the number of characters and delete that number of characters
  8. 如果是匹配,请计算字符数并删除字符数
  9. Input the suggestion suggested by the lexicon
  10. 输入词汇所建议的建议。
  11. Clear the string and start again
  12. 清除字符串并重新开始

Additionally you could also use UITextChecker to offer more advanced auto-correct features.

此外,您还可以使用UITextChecker提供更高级的自动更正功能。

Code (in Objective-C, this may not be 100% accurate I wrote in SO while on the bus but it should do):

代码(在Objective-C中,我在公共汽车上写的可能不是100%准确,但应该是这样):

UILexicon *lexicon;
NSString *currentString;

-(void)viewDidLoad {
     [self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) {
         self.lexicon = receivedLexicon;
     }];
}

-(IBAction)myTypingAction:(UIButton *)sender {
    [documentProxy insertText:sender.title]; 
    [currentString stringByAppendingString:sender.title];
}

-(IBAction)space {
   [documentProxy insertText:@" "];
   for (UILexiconEntry *lexiconEntry in lexicon.entries) {
       if (lexiconEntry.userInput isEqualToString:currentString) {
            for (int i = 0; currentString.length >=i ; i++) { 
                 [documentProxy deleteTextBackwards];
            }
            [documentProxy insertText:lexiconEntry.documentText];
            currentString = @"";  
        }
    } 
}

Feel free to comment if you have any more questions.

如果你有任何问题,请随时发表意见。

Source: Personal experience with iOS 8 keyboards and UILexicon

来源:iOS 8键盘和UILexicon的个人体验

#2


6  

With regards to auto-correction, I was able to add it using link. Here's the code snippet I used from the link:

关于自动校正,我可以使用link添加它。下面是我在链接中使用的代码片段:

UITextChecker *checker = [[UITextChecker alloc] init];

  NSRange checkRange = NSMakeRange(0, self.txView.text.length);

  NSRange misspelledRange = [checker rangeOfMisspelledWordInString:self.txView.text 
                                                             range:checkRange
                                                        startingAt:checkRange.location
                                                              wrap:NO 
                                                          language:@"en_US"];

  NSArray *arrGuessed = [checker guessesForWordRange:misspelledRange inString:self.txView.text language:@"en_US"];

  self.txView.text = [self.txView.text stringByReplacingCharactersInRange:misspelledRange 
                                                               withString:[arrGuessed objectAtIndex:0]];

The full documentation from Apple can be found here.

苹果的完整文档可以在这里找到。

#3


4  

Although I have not personally tried creating a custom keyboard, I am basing this answer on what I can see in the documentation.

虽然我个人还没有尝试过创建自定义键盘,但我的回答是基于我在文档中看到的。

In your keyboard, create a property called entries of type [AnyObject] (Array of AnyObjects).

在您的键盘中,创建一个属性,名为“输入类型[AnyObject] (AnyObject数组)”。

In your init method, or wherever you create the keyboard, call this method:

在init方法中,或者在创建键盘的任何地方,调用此方法:

requestSupplementaryLexiconWithCompletion(completionHandler: {
    lexicon in 
    self.entries = lexicon.entries
})

I suspect that entries is actually an array of Strings or NSStrings, but it could be a dictionary or some other type. When testing this out, try figuring out what type is actually contained in entries before figuring out your logic.

我怀疑条目实际上是字符串或nsstring的数组,但它可以是字典或其他类型。在测试时,在理解逻辑之前,先试着找出条目中实际包含的类型。

I do not believe there is a way to get Apple's default autocorrect options currently. However, this WWDC talk gives insight about how they made autocorrect work in the original iPhone OS (around the 30 minute mark).

我不相信目前有什么方法可以得到苹果默认的自动更正选项。然而,这次WWDC的演讲让我们了解了他们是如何在最初的iPhone操作系统(大约30分钟)中实现自动纠错的。

He mentions using a binary search of the array, which leads me to believe that this array is sorted. Of course, much could have changed since the first iPhone came out...

他提到了使用数组的二进制搜索,这让我相信这个数组是有序的。当然,自从第一代iPhone问世以来,情况可能发生了很大变化。

Good luck figuring out this new API!

祝您好运,找到这个新的API!

#4


2  

This is the way you can actually access Lexicon words:

这是你可以访问词汇的方式:

[self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) {
    self.lexicon = receivedLexicon;

    for (UILexiconEntry *word in self.lexicon.entries) {
        // Text to be inserted into a text input object by a custom keyboard, corresponding to the userInput value in the same lexicon entry.
        NSLog(@"%@",word.documentText);
        // Text to match, during user input, to provide appropriate output to a text document from the documentText value in the same lexicon entry.
        NSLog(@"%@",word.userInput);
    }
}];

#5


1  

Every custom keyboard (independent of the value of its RequestsOpenAccess key) has access to a basic autocorrection lexicon through the UILexicon class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text. The UILexicon object contains words from various sources, including:

每个自定义键盘(独立于其RequestsOpenAccess键的值)都可以通过UILexicon类访问一个基本的自动修正词汇。利用这个类,以及您自己设计的词典,在用户输入文本时提供建议和自动更正。UILexicon对象包含来自各种来源的词,包括:

Unpaired first names and last names from the user’s Address Book database Text shortcuts defined in the Settings > General > Keyboard > Shortcuts list A common words dictionary that includes the names of Apple products

从用户的通讯录数据库文本快捷键中定义的未配对的名字和姓氏,在>通用>的>键盘上列出了一个常用的单词字典,其中包括苹果产品的名称。

#6


1  

In case anyone is still looking into this, I found a really nice C++ predictive text library called Presage. It seems to do a good job based on the demo but I'm having a lot of trouble trying to integrate it as a library (see my question here).

如果有人还在研究这个,我找到了一个很好的c++预测文本库,叫做Presage。它似乎在演示的基础上做得很好,但是我在尝试将它集成为一个库时遇到了很多麻烦(请参见我的问题)。

Let me know if anyone has any ideas, very interested in getting this working!

如果有人有任何想法,请告诉我,非常想让这个工作!

#7


1  

Actually, UILexicon is just a way to get some user-specific words that your spellchecking system should't try to fix. Probably, the most common way to use it is to fill out UITextChecker's list of ignored words.

实际上,UILexicon只是一种获取特定于用户的单词的方法,你的拼写检查系统不应该试图修复这些单词。也许,最常用的方法是填写UITextChecker的被忽略的单词列表。

let lexicon: UILexicon = ...
let checker: UITextChecker = ...

for entry in lexicon.entries {
    if entry.documentText == entry.userInput {
        checker.ignoreWord(entry.documentText)
    }
}

Additionally, UILexicon can be used as source of autoreplaced shortcuts like ("omw" = "On my way!"), but it is not autocorrection in terms of spelling.

此外,UILexicon可以作为自动放置的快捷方式的来源,比如(“omw”=“On my way!”),但在拼写方面它并不是自动更正。

#8


0  

You can use below logic for AutoCorrect & it will also work in iOS 10

你可以使用下面的逻辑进行自动更正&它也可以在ios10中使用

-(void)didClickAtAlphaNumericKeyboardKey:(NSString *)value {

    if ([value isEqualToString:@" "]) {
            UITextChecker *checker = [[UITextChecker alloc] init];
            currentString = self.textDocumentProxy.documentContextBeforeInput;
            NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
            NSArray *components = [currentString componentsSeparatedByCharactersInSet:charSet];
            NSString *lastWord = components.lastObject;

            NSRange checkRange = NSMakeRange(0, lastWord.length);
            NSRange misspelledRange = [checker rangeOfMisspelledWordInString:lastWord
                                                                       range:checkRange
                                                                  startingAt:checkRange.location
                                                                        wrap:NO
                                                                    language:@"en_US"];

            NSArray *guessedWord = [checker guessesForWordRange:misspelledRange inString:lastWord language:@"en_US"];

            if (guessedWord && guessedWord.count > 0) {
                for (int i = 0; lastWord.length >i ; i++) {
                    [self.textDocumentProxy deleteBackward];
                }
                [self.textDocumentProxy insertText:[guessedWord objectAtIndex:0]];
            }
    }

    [self.textDocumentProxy insertText:value];
}

#1


22  

Implementing the lexicon would look pretty much like this:

实现lexicon的方式大致如下:

  1. Use requestSupplementaryLexiconWithCompletion() to get the lexicon upon launch once.
  2. 使用requestSupplementaryLexiconWithCompletion()在启动时获取lexicon。
  3. Each type text is inputted add it to a NSString (tracking the current word)
  4. 输入的每个类型文本都将其添加到NSString(跟踪当前单词)
  5. When user presses space (end of curent word) check the string against the lexicon
  6. 当用户按空格(curent word结尾)时,根据字典检查字符串
  7. If it's a match count the number of characters and delete that number of characters
  8. 如果是匹配,请计算字符数并删除字符数
  9. Input the suggestion suggested by the lexicon
  10. 输入词汇所建议的建议。
  11. Clear the string and start again
  12. 清除字符串并重新开始

Additionally you could also use UITextChecker to offer more advanced auto-correct features.

此外,您还可以使用UITextChecker提供更高级的自动更正功能。

Code (in Objective-C, this may not be 100% accurate I wrote in SO while on the bus but it should do):

代码(在Objective-C中,我在公共汽车上写的可能不是100%准确,但应该是这样):

UILexicon *lexicon;
NSString *currentString;

-(void)viewDidLoad {
     [self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) {
         self.lexicon = receivedLexicon;
     }];
}

-(IBAction)myTypingAction:(UIButton *)sender {
    [documentProxy insertText:sender.title]; 
    [currentString stringByAppendingString:sender.title];
}

-(IBAction)space {
   [documentProxy insertText:@" "];
   for (UILexiconEntry *lexiconEntry in lexicon.entries) {
       if (lexiconEntry.userInput isEqualToString:currentString) {
            for (int i = 0; currentString.length >=i ; i++) { 
                 [documentProxy deleteTextBackwards];
            }
            [documentProxy insertText:lexiconEntry.documentText];
            currentString = @"";  
        }
    } 
}

Feel free to comment if you have any more questions.

如果你有任何问题,请随时发表意见。

Source: Personal experience with iOS 8 keyboards and UILexicon

来源:iOS 8键盘和UILexicon的个人体验

#2


6  

With regards to auto-correction, I was able to add it using link. Here's the code snippet I used from the link:

关于自动校正,我可以使用link添加它。下面是我在链接中使用的代码片段:

UITextChecker *checker = [[UITextChecker alloc] init];

  NSRange checkRange = NSMakeRange(0, self.txView.text.length);

  NSRange misspelledRange = [checker rangeOfMisspelledWordInString:self.txView.text 
                                                             range:checkRange
                                                        startingAt:checkRange.location
                                                              wrap:NO 
                                                          language:@"en_US"];

  NSArray *arrGuessed = [checker guessesForWordRange:misspelledRange inString:self.txView.text language:@"en_US"];

  self.txView.text = [self.txView.text stringByReplacingCharactersInRange:misspelledRange 
                                                               withString:[arrGuessed objectAtIndex:0]];

The full documentation from Apple can be found here.

苹果的完整文档可以在这里找到。

#3


4  

Although I have not personally tried creating a custom keyboard, I am basing this answer on what I can see in the documentation.

虽然我个人还没有尝试过创建自定义键盘,但我的回答是基于我在文档中看到的。

In your keyboard, create a property called entries of type [AnyObject] (Array of AnyObjects).

在您的键盘中,创建一个属性,名为“输入类型[AnyObject] (AnyObject数组)”。

In your init method, or wherever you create the keyboard, call this method:

在init方法中,或者在创建键盘的任何地方,调用此方法:

requestSupplementaryLexiconWithCompletion(completionHandler: {
    lexicon in 
    self.entries = lexicon.entries
})

I suspect that entries is actually an array of Strings or NSStrings, but it could be a dictionary or some other type. When testing this out, try figuring out what type is actually contained in entries before figuring out your logic.

我怀疑条目实际上是字符串或nsstring的数组,但它可以是字典或其他类型。在测试时,在理解逻辑之前,先试着找出条目中实际包含的类型。

I do not believe there is a way to get Apple's default autocorrect options currently. However, this WWDC talk gives insight about how they made autocorrect work in the original iPhone OS (around the 30 minute mark).

我不相信目前有什么方法可以得到苹果默认的自动更正选项。然而,这次WWDC的演讲让我们了解了他们是如何在最初的iPhone操作系统(大约30分钟)中实现自动纠错的。

He mentions using a binary search of the array, which leads me to believe that this array is sorted. Of course, much could have changed since the first iPhone came out...

他提到了使用数组的二进制搜索,这让我相信这个数组是有序的。当然,自从第一代iPhone问世以来,情况可能发生了很大变化。

Good luck figuring out this new API!

祝您好运,找到这个新的API!

#4


2  

This is the way you can actually access Lexicon words:

这是你可以访问词汇的方式:

[self requestSupplementaryLexiconWithCompletion:^(UILexicon *receivedLexicon) {
    self.lexicon = receivedLexicon;

    for (UILexiconEntry *word in self.lexicon.entries) {
        // Text to be inserted into a text input object by a custom keyboard, corresponding to the userInput value in the same lexicon entry.
        NSLog(@"%@",word.documentText);
        // Text to match, during user input, to provide appropriate output to a text document from the documentText value in the same lexicon entry.
        NSLog(@"%@",word.userInput);
    }
}];

#5


1  

Every custom keyboard (independent of the value of its RequestsOpenAccess key) has access to a basic autocorrection lexicon through the UILexicon class. Make use of this class, along with a lexicon of your own design, to provide suggestions and autocorrections as users are entering text. The UILexicon object contains words from various sources, including:

每个自定义键盘(独立于其RequestsOpenAccess键的值)都可以通过UILexicon类访问一个基本的自动修正词汇。利用这个类,以及您自己设计的词典,在用户输入文本时提供建议和自动更正。UILexicon对象包含来自各种来源的词,包括:

Unpaired first names and last names from the user’s Address Book database Text shortcuts defined in the Settings > General > Keyboard > Shortcuts list A common words dictionary that includes the names of Apple products

从用户的通讯录数据库文本快捷键中定义的未配对的名字和姓氏,在>通用>的>键盘上列出了一个常用的单词字典,其中包括苹果产品的名称。

#6


1  

In case anyone is still looking into this, I found a really nice C++ predictive text library called Presage. It seems to do a good job based on the demo but I'm having a lot of trouble trying to integrate it as a library (see my question here).

如果有人还在研究这个,我找到了一个很好的c++预测文本库,叫做Presage。它似乎在演示的基础上做得很好,但是我在尝试将它集成为一个库时遇到了很多麻烦(请参见我的问题)。

Let me know if anyone has any ideas, very interested in getting this working!

如果有人有任何想法,请告诉我,非常想让这个工作!

#7


1  

Actually, UILexicon is just a way to get some user-specific words that your spellchecking system should't try to fix. Probably, the most common way to use it is to fill out UITextChecker's list of ignored words.

实际上,UILexicon只是一种获取特定于用户的单词的方法,你的拼写检查系统不应该试图修复这些单词。也许,最常用的方法是填写UITextChecker的被忽略的单词列表。

let lexicon: UILexicon = ...
let checker: UITextChecker = ...

for entry in lexicon.entries {
    if entry.documentText == entry.userInput {
        checker.ignoreWord(entry.documentText)
    }
}

Additionally, UILexicon can be used as source of autoreplaced shortcuts like ("omw" = "On my way!"), but it is not autocorrection in terms of spelling.

此外,UILexicon可以作为自动放置的快捷方式的来源,比如(“omw”=“On my way!”),但在拼写方面它并不是自动更正。

#8


0  

You can use below logic for AutoCorrect & it will also work in iOS 10

你可以使用下面的逻辑进行自动更正&它也可以在ios10中使用

-(void)didClickAtAlphaNumericKeyboardKey:(NSString *)value {

    if ([value isEqualToString:@" "]) {
            UITextChecker *checker = [[UITextChecker alloc] init];
            currentString = self.textDocumentProxy.documentContextBeforeInput;
            NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
            NSArray *components = [currentString componentsSeparatedByCharactersInSet:charSet];
            NSString *lastWord = components.lastObject;

            NSRange checkRange = NSMakeRange(0, lastWord.length);
            NSRange misspelledRange = [checker rangeOfMisspelledWordInString:lastWord
                                                                       range:checkRange
                                                                  startingAt:checkRange.location
                                                                        wrap:NO
                                                                    language:@"en_US"];

            NSArray *guessedWord = [checker guessesForWordRange:misspelledRange inString:lastWord language:@"en_US"];

            if (guessedWord && guessedWord.count > 0) {
                for (int i = 0; lastWord.length >i ; i++) {
                    [self.textDocumentProxy deleteBackward];
                }
                [self.textDocumentProxy insertText:[guessedWord objectAtIndex:0]];
            }
    }

    [self.textDocumentProxy insertText:value];
}