How to use autocorrection and shortcut list in iOS8 custom keyboard?

后端 未结 9 933
慢半拍i
慢半拍i 2020-12-07 17:22

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.

相关标签:
9条回答
  • 2020-12-07 17:28

    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:

    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

    0 讨论(0)
  • 2020-12-07 17:29

    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.

    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.

    0 讨论(0)
  • 2020-12-07 17:33

    Implementing the lexicon would look pretty much like this:

    1. Use requestSupplementaryLexiconWithCompletion() to get the lexicon upon launch once.
    2. Each type text is inputted add it to a NSString (tracking the current word)
    3. When user presses space (end of curent word) check the string against the lexicon
    4. If it's a match count the number of characters and delete that number of characters
    5. Input the suggestion suggested by the lexicon
    6. Clear the string and start again

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

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

    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

    0 讨论(0)
  • 2020-12-07 17:34

    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).

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

    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.

    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).

    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...

    Good luck figuring out this new API!

    0 讨论(0)
  • 2020-12-07 17:35

    With regards to auto-correction, I was able to add it using link. Here's the code snippet I used from the 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.

    0 讨论(0)
  • 2020-12-07 17:35

    Rachits answer above in swift 4. Works with iOS 12

    I have this helper to check wether the current string to be tested by UITextChecker is not a space

    func validate(string: String?) -> Bool {
        guard let text = string,
            !text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).isEmpty else {
                return false
        }
        return true
    }
    

    The text checker is then in my "Spacebar", "Spacebar double tapped" & "return" methods. The example below is in my "Space" method

    let textChecker = UITextChecker()
        let currentString = self.textDocumentProxy.documentContextBeforeInput
        if validate(string: currentString) {
            let charSet = NSCharacterSet.whitespacesAndNewlines
            let components = currentString?.components(separatedBy: charSet)
            let lastWord = components?.last
            let checkRange = NSMakeRange(0, lastWord?.count ?? 0)
            let misspelledRange = textChecker.rangeOfMisspelledWord(in: lastWord!, range: checkRange, startingAt: checkRange.location, wrap: false, language: "en_US")
            if misspelledRange.length != 0 {
                let guessedWord: Array = textChecker.guesses(forWordRange: misspelledRange, in: lastWord!, language: "en_US")!
                if  guessedWord.count > 0 {
                    var i = 0
                    while (lastWord?.length)! > i {
                        textDocumentProxy.deleteBackward()
                        i += 1
                    }
                    self.textDocumentProxy.insertText(guessedWord[0])
    
                }
            }
        }
    
    
        self.textDocumentProxy.insertText(" ")
    

    I had to make two changes to Rachits code. First to validate the currentString since it throws an exception if you press space bar twice. And second to check if the misspelled range is not 0 because that was also throwing an exception which I am yet to figure out why. But this works for me now as is.

    0 讨论(0)
提交回复
热议问题