Search code examples
iosios8

Check if predictive text is enabled


I would like to know if there is any way to check wether predictive text (the grey boxes above the keyboard) is enabled.

I need this to scroll a view a few pixel more to the top when the textfield gets its focus. I get the size of the keyboard with: CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;


Solution

  • Use end frame to get the last position the keyboard will end up. So in your keyboardWillShow: notification callback get the keyboard end frame.

    - (void)keyboardWillShow:(NSNotification *)notification
    {
        NSDictionary *userInfo = notification.object;
        CGRect keyboardEndFrame;
        [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
    
        // Use keyboardEndFrame
    }
    

    This even works when user resizes the predictive text view (shrink/expand) and also works if you have an input accessory view.

    Edit

    The real answer to the title of this question is different. As of now, there is no obvious way to find out if the predictive text is enabled. So I came up a solution which checks keyboard frame with different autocorrection types.

    ZSTKeyboardChecker.h

    #import <UIKit/UIKit.h>
    
    @interface ZSTKeyboardChecker : NSObject
    
    - (BOOL)isPredictiveTextEnabledForTextField:(UITextField *)textField;
    
    @end
    

    ZSTKeyboardChecker.m

    @interface ZSTKeyboardChecker ()
    
    @property (assign, nonatomic) CGRect keyboardEndFrame;
    
    @end
    
    @implementation ZSTKeyboardChecker
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        }
        return self;
    }
    
    - (BOOL)isPredictiveTextEnabledForTextField:(UITextField *)textField
    {
        if (textField.autocorrectionType == UITextSpellCheckingTypeNo) {
            return NO;
        }
    
        BOOL isFirstResponder = [textField isFirstResponder];
        BOOL autoCorrectionType = [textField autocorrectionType];
    
        [textField resignFirstResponder];
    
        // Get the frame with possibly including predictive text
        [textField becomeFirstResponder];
        CGRect predictiveKeyboardEndFrame = self.keyboardEndFrame;
        [textField resignFirstResponder];
    
        // Get the keyboard frame without predictive text
        textField.autocorrectionType = UITextSpellCheckingTypeNo;
        [textField becomeFirstResponder];
        CGRect defaultKeyboardEndFrame = self.keyboardEndFrame;
        [textField resignFirstResponder];
    
        // Restore state
        textField.autocorrectionType = autoCorrectionType;
        if (isFirstResponder) {
            [textField becomeFirstResponder];
        }
    
        BOOL isPredictiveTextEnabled = !CGPointEqualToPoint(predictiveKeyboardEndFrame.origin, defaultKeyboardEndFrame.origin);
        return isPredictiveTextEnabled;
    }
    
    - (void)keyboardWillShow:(NSNotification *)notification
    {
        NSDictionary *userInfo = notification.object;
        CGRect keyboardEndFrame;
        [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
    
        self.keyboardEndFrame = keyboardEndFrame;
    }
    
    @end
    

    Usage (You may want to check it only once)

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        ZSTKeyboardChecker *keyboardChecker = [[ZSTKeyboardChecker alloc] init];
        BOOL isPredictiveTextEnabled = [keyboardChecker isPredictiveTextEnabledForTextField:self.textField];
    
        NSLog(@"Enabled: %d", isPredictiveTextEnabled);
    }