iOS 8中,当键盘出现时UIView不会上移

10

我正在开发一个聊天应用程序,其中包含UITableView和一个包含UITextFieldUIButtonUIView。 当键盘出现时,我使用以下代码将UIView向上移动。

(void)keyboardWillShow:(NSNotification *)notification
{

    NSDictionary* info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    [UIView animateWithDuration:0.2f animations:^{

        CGRect frame = self.inputView.frame;
       UIInterfaceOrientation orientation = self.interfaceOrientation;
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation ==        UIInterfaceOrientationLandscapeRight)
            frame.origin.y -= kbSize.width;
        else
            frame.origin.y -= kbSize.height;

        self.inputView.frame = frame;
       ;
    }];
}

在iOS 7及以下版本中,这段代码运行良好,但在iOS 8中UIView无法显示在键盘上方。

请问有谁能够提供可能的问题或者iOS 8中是否发生了什么变化?

4个回答

17

您的代码似乎是正确的,但我更倾向于使用UIKeyboardDidChangeFrameNotification或UIKeyboardWillChangeFrameNotification,因为它们会在键盘处于视图中并且预测文本栏上下移动时告诉您键盘框架的变化。

在您的ViewDidLoad中添加以下内容:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardFrameDidChange:)
                                             name:UIKeyboardDidChangeFrameNotification object:nil];

然后将此方法粘贴到您的ViewController中

-(void)keyboardFrameDidChange:(NSNotification*)notification{
    NSDictionary* info = [notification userInfo];

    CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    [yourView setFrame:CGRectMake(0, kKeyBoardFrame.origin.y-yourView.frame.size.height, 320, yourView.frame.size.height)];
}

这将处理所有键盘情况,例如当其上下移动或更改其带有预测文本栏的框架时,并在离开视图时还会移除观察器。


这里的 "y" 无法编译。 - ngb
@ngb 你到底在说什么? - Pankaj Wadhwa
@pankajwadhwa 我的情况没什么变化。我有一个view固定在了底部空间。我尝试了你上面提供的代码,可以获取到kKeyBoardFrame的值。但是 [yourView setFrame:...] 却不起作用。可能是什么原因呢?谢谢。 - Sreejith

2
接受的答案几乎正确。要使您的视图动画与键盘的动画匹配,您需要使用UIKeyboardWillChangeFrameNotification而不是UIKeyboardDidChangeFrameNotification。这样,您启动的动画将精确匹配键盘的动画。以下是完成整个操作的一些代码。我使用键盘的动画来驱动我的自动布局约束常量的动画,但您可以轻松地将其调整为动画化整个视图框架。(请注意,我们必须使用旧学校风格的动画来连接到UIKeyboardCurveInfoKey,它提供与键盘动画完全匹配的动画曲线。) 在viewDidLoad中:
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardFrameDidChange:)
                                             name:UIKeyboardWillChangeFrameNotification
                                           object:nil];

在ViewController中:

- (void)keyboardFrameDidChange:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];

    CGRect kKeyBoardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat height = kKeyBoardFrame.size.height; 
    [self.view removeConstraints:self.verticalButtonConstraints];
    NSDictionary *metrics = @{@"height" : @(height)};
    NSDictionary *views = @{@"nextButton" : self.nextButton};

    self.verticalButtonConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:  [nextButton(52)]-(height)-|" options:0 metrics:metrics views:views];
    [self.view addConstraints:self.verticalButtonConstraints];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.view layoutIfNeeded];
   [UIView commitAnimations];

}


1

我最近遇到了一个问题,做了个发现想要分享一下。在iOS 8中,当键盘即将出现或消失时,主视图的子视图的布局传递会被执行。而在iOS 7中,这些传递并不会被执行。因此,如果你尝试在keyBoardWillShow或keyboardWillChangeFrame中对主视图的子视图进行动画处理,布局传递会撤销动画,并且你尝试动画化的子视图会回到它们原来的位置。这就是为什么使用keyboardDidChangeFrame可以用于子视图的动画处理,而keyboardWillChangeFrame则不行。

我还注意到一个奇怪的事情,就是这些调用的时间。似乎第一次打开应用程序后键盘出现时,调用keyboardDidChangeFrame太晚了,不能与键盘一起动画移动,但是在第二次及以后显示键盘时,调用keyboardDidChangeFrame会更早一些,看起来你实际上可以随着键盘一起动画移动视图。

必须指出的是,我使用C#和Xamarin作为iOS的开发平台,因此在使用Swift或Obj-C时可能会有所不同。


0

你可以使用一个附加视图(accessoryView),它会附加在键盘顶部。或者,如果你想更精细地定制,你可以像 @pankaj_wadwha 所解释的那样使用通知来获取框架信息。额外奖励:你还可以获得动画信息(如速度),以便你的视图可以完美地随着键盘移动。


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