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

时间:2014-09-21 04:48:17

标签: uitableview uiview keyboard uitextfield ios8

我正在开发一个聊天应用,其中包含UITableViewUIView,其中包含UITextFieldUIButton。我正在使用以下代码在键盘出现时向上移动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 个答案:

答案 0 :(得分: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)];
}

这将处理所有键盘情况,例如它的向上或向下或用预测文本栏更改其框架

并在离开视图时删除观察者

答案 1 :(得分: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];

}

答案 2 :(得分:1)

我刚刚遇到这个并发现了我认为我会分享的发现。在iOS 8中,只要键盘即将出现或即将消失,主视图子视图的布局传递就会完成。这些传递不会在iOS 7上完成。因此,如果您尝试在keyBoardWillShow或keyboardWillChangeFrame中为主视图的子视图设置动画,则动画将通过布局传递撤消,您尝试设置动画的子视图将移回其原来的位置。这就是为什么keyboardDidChangeFrame可以为子视图设置动画,而keyboardWillChangeFrame则没有。

我注意到的一些奇怪的事情是这些电话何时发出的时间。这似乎是第一次在启动应用程序后出现键盘,对keyboardDidChangeFrame的调用发生得太晚,无法使用键盘进行动画处理,因此它们一起向上滑动,但在键盘显示的第二次和后续时间,对keyboardDidChangeFrame的调用更快地发生,似乎你可以实际上为键盘设置动画。

我必须注意,我使用C#和Xamarin作为iOS的开发平台,所以当使用Swift或Obj-C时,可能不同。

答案 3 :(得分:0)

您可以使用accessoryView,它将自身附加到键盘的顶部。或者,如果您想要更多的自定义功能,可以使用@pankaj_wadwha所解释的通知来获取帧信息。额外奖励:您还可以获取动画信息(例如速度),以便您的视图完美地与键盘一起移动。