问题 检查是否启用了预测文本


我想知道是否有任何方法可以检查其他预测文本(键盘上方的灰色框)是否已启用。

当文本字段获得焦点时,我需要这样可以将视图加到顶部几个像素。我得到了键盘的大小: CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;


7013
2017-09-23 11:29


起源



答案:


使用结束帧来获得键盘结束的最后位置。所以在你的 keyboardWillShow: 通知回调获取键盘结束帧。

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

    // Use keyboardEndFrame
}

这甚至可以在用户调整预测文本视图(缩小/展开)时调整,如果您有输入附件视图也可以。

编辑

这个问题的真正答案是不同的。截至目前,没有明显的方法可以确定是否启用了预测文本。所以我提出了一个解决方案,用不同的自动更正类型检查键盘框架。

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

用法(您可能只想检查一次)

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    ZSTKeyboardChecker *keyboardChecker = [[ZSTKeyboardChecker alloc] init];
    BOOL isPredictiveTextEnabled = [keyboardChecker isPredictiveTextEnabledForTextField:self.textField];

    NSLog(@"Enabled: %d", isPredictiveTextEnabled);
}

9
2017-09-23 13:53



两个键 UIKeyboardFrameEndUserInfoKey 和 UIKeyboardFrameBeginUserInfoKey 给我相同的价值观 keyboardWillShow。两者都给我一个253.0的高度值。我试过了: [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height - palme
实际上,当您启用/禁用建议时,键盘的高度和原点都应该更改。向下滑动预测文本栏会发生什么?不是 keyboardEndFrame 变化? - irmakcanozsut
当然你绝对正确。高度不会改变。很棒的回答,谢谢。我只需要改变我的计算来移动视图。仍然失望为什么cocoa没有提供实际的键盘(键盘+预测文本)高度。 - palme
我发现当向下滑动预测文本栏时,原点保持不变,高度(显然)会发生变化,但仍然高于“默认”大小...我最终也检查了高度,记住了这一点。 - alasker


答案:


使用结束帧来获得键盘结束的最后位置。所以在你的 keyboardWillShow: 通知回调获取键盘结束帧。

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

    // Use keyboardEndFrame
}

这甚至可以在用户调整预测文本视图(缩小/展开)时调整,如果您有输入附件视图也可以。

编辑

这个问题的真正答案是不同的。截至目前,没有明显的方法可以确定是否启用了预测文本。所以我提出了一个解决方案,用不同的自动更正类型检查键盘框架。

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

用法(您可能只想检查一次)

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    ZSTKeyboardChecker *keyboardChecker = [[ZSTKeyboardChecker alloc] init];
    BOOL isPredictiveTextEnabled = [keyboardChecker isPredictiveTextEnabledForTextField:self.textField];

    NSLog(@"Enabled: %d", isPredictiveTextEnabled);
}

9
2017-09-23 13:53



两个键 UIKeyboardFrameEndUserInfoKey 和 UIKeyboardFrameBeginUserInfoKey 给我相同的价值观 keyboardWillShow。两者都给我一个253.0的高度值。我试过了: [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height - palme
实际上,当您启用/禁用建议时,键盘的高度和原点都应该更改。向下滑动预测文本栏会发生什么?不是 keyboardEndFrame 变化? - irmakcanozsut
当然你绝对正确。高度不会改变。很棒的回答,谢谢。我只需要改变我的计算来移动视图。仍然失望为什么cocoa没有提供实际的键盘(键盘+预测文本)高度。 - palme
我发现当向下滑动预测文本栏时,原点保持不变,高度(显然)会发生变化,但仍然高于“默认”大小...我最终也检查了高度,记住了这一点。 - alasker