如何获取iOS 8.3表情符号键盘的高度?

13

我能够处理两个事件:当键盘出现和键盘隐藏时。在iOS 8.2及更早版本上一切正常。

但是如何处理当您更改键盘语言时的事件呢?当您将英文键盘更改为表情符号键盘时,表情符号键盘的高度(在iOS 8.3中)会变得较大并且会遮挡内容。

或者也许您有解决方案来控制iOS 8.3表情符号键盘的高度呢? 输入图像描述


3
请查看UIKeyboardWillChangeFrameNotification/UIKeyboardDidChangeFrameNotification。每次键盘框架发生变化时都会触发这些通知,无论键盘是否隐藏。例如,更改键盘类型(ASCII/表情符号)或切换键盘上方的预测文本栏。 - n00bProgrammer
好的。让我更新一下我的Xcode和模拟器,然后我会给你一个优化的可行解决方案。大概需要一个小时左右。 - n00bProgrammer
4个回答

13

好的。看着我的旧代码,我记得,我没有使用两个观察者(UIKeyboardDidShowNotification/UIKeyboardDidHideNotification)。我使用一个单独的观察者(UIKeyboardWillChangeFrameNotification),它会在每个事件上被激活:键盘隐藏、键盘显示、键盘改变框架。

在我的情况下,文本框和发送按钮是嵌套在一个 UIView 中的,并且此视图添加在 UIViewControllerview 中,高于其他所有内容。

我在 viewDidAppear 中添加观察器,并在 viewWillDisappear 中删除观察器。(以避免在视图不活动时触发任何通知)。

以上信息对您的情况并非必要,只是为了提供信息而添加的。相关代码如下:

添加观察者:

- (void) viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

处理通知:

- (void) keyboardWillChangeFrame:(NSNotification*)notification {

    NSDictionary* notificationInfo = [notification userInfo];

    CGRect keyboardFrame = [[notificationInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    [UIView animateWithDuration:[[notificationInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]
                          delay:0
                        options:[[notificationInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]
                     animations:^{

                         CGRect frame = self.textViewContainer.frame;
                         frame.origin.y = keyboardFrame.origin.y - frame.size.height;
                         self.textViewContainer.frame = frame;

                     } completion:nil];
}

您可能需要对frame.origin.y...行进行一些调整,以进行正确的计算。我不知道您是否有UITabBarController或底部的任何栏。这里最安全的选择是:

frame.origin.y = self.view.frame.size.height - keyboardFrame.size.height - X;

当您的VC覆盖整个屏幕时,X为0。否则,请使用任何底部栏的高度。


在这种情况下,布局约束条件需要更新。 - n00bProgrammer
虽然Remus也提供了正确的答案,但这个更正确且更容易实现/代码更少。完美运行。 - user3344977
是的,但是它之后如何取消键盘。我启用了点击手势来取消,但它仍然停留在键盘原来的位置上...你能帮我吗? - Joshua Hart

6

我遇到了同样的问题。只需将UIKeyboardFrameBeginUserInfoKey替换为UIKeyboardFrameEndUserInfoKey。:-)

这对我有用。


4
值得注意的是,启用建议文本后,表情符号键盘与标准键盘的高度相同。
为了正确确定键盘高度并调整视图,请添加以下观察者:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];

然后我使用以下方法来进行键盘调整的动画。实际上,你只需要keyboardBounds对象即可,但如果你正在使用AutoLayout,则应按照以下方式执行:

- (void)keyboardDidShow:(NSNotification *)notification
{
    [self scrollControlBarTo:notification up:YES];
}

-(void)keyboardDidHide:(NSNotification *)notification
{
    [self scrollControlBarTo:notification up:NO];
}

- (void)scrollControlBarTo:(NSNotification *)notification up:(BOOL)up
{
    [_keyboardControlsBar layoutIfNeeded];
    CGRect keyboardBounds;
    NSDictionary *info = [notification userInfo];
    NSNumber *number = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    double duration = [number doubleValue];
    [[info objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardBounds];
    UIViewAnimationCurve curve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];

    [UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         [UIView setAnimationCurve:curve];
                         _keyboardControlsBarBottomConstraint.constant = (up) ? keyboardBounds.size.height : 0;
                         [self.view layoutIfNeeded];
                     } completion:nil];
}

能否确定键盘动画时间呢?那就太完美了! - Dunes Buggy
更新了我的答案以包含相关部分。https://dev59.com/0XM_5IYBdhLWcg3wWRkF - brandonscript
1
请参考https://dev59.com/CGMk5IYBdhLWcg3wyw_H,了解iOS 7键盘动画的未记录动画曲线。 - jszumski
不错,@jszumski - 更新了答案,似乎是最简单的实现方式。 - brandonscript

0

上面的代码但是用Swift

func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}

...

func keyboardWillChangeFrame(_ notification: Notification?) {

let notificationInfo = notification?.userInfo

let keyboardFrame = notificationInfo?[UIResponder.keyboardFrameEndUserInfoKey]?.cgRectValue

UIView.animate(withDuration: TimeInterval((notificationInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.floatValue ?? 0.0), delay: 0, options: UIView.AnimationOptions(rawValue: (notificationInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.intValue ?? 0), animations: {

    let frame = self.textViewContainer.frame


     frame.origin.y = (keyboardFrame?.origin.y ?? 0.0) - frame.size.height
        self.textViewContainer.frame = frame

    })
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接