在eventFirstResponder或resignFirstResponder的情况下,将对象保持在键盘顶部? [英] Keeping object on top of keyboard in the event of becomeFirstResponder or resignFirstResponder?

查看:119
本文介绍了在eventFirstResponder或resignFirstResponder的情况下,将对象保持在键盘顶部?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在键盘上有一个UITextField。点击它时,它应该粘在键盘顶部并顺利向上移动。我不知道键盘的确切持续时间和动画类型,所以它真的很颠簸。这就是我所拥有的:

I currently have a UITextField on top of a keyboard. When you tap it, it should stick on top of the keyboard and move up smoothly. I don't know the exact duration and animation type of the keyboard, so it's really bumpy. Here's what I have:

[theTextView resignFirstResponder];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
// Frame changes go here (move down 216px)
[UIView commitAnimations];

[theTextView becomeFirstResponder];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.25];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
// Frame changes go here (move up 216px)
[UIView commitAnimations];

如果有人之前做过这样的事情,我想知道你用来做这个的设置动画流畅,让它看起来像是卡在键盘的顶部。

If anyone has done something like this before, I would like to know the settings you used to make the animation smooth and make it appear that the bar is "stuck" to the top of the keyboard.

推荐答案

UIKit发布 UIKeyboardWillShowNotification 显示键盘时, UIKeyboardWillHideNotification 隐藏键盘时。这些通知包含正确设置 UITextField 动画所需的一切。

UIKit posts UIKeyboardWillShowNotification when it shows the keyboard, and UIKeyboardWillHideNotification when it hides the keyboard. These notifications contain everything you need to properly animate your UITextField.

假设你的 UITextField 位于名为 myTextField 的属性中。

Let's say your UITextField is in a property called called myTextField.

首先,您需要注册某处的通知。您注册的位置取决于移动 myTextField 的对象。在我的项目中,该字段的superview负责,因为我从笔尖加载我的UI,我在superview的 awakeFromNib 中执行:

First, you need to register for the notifications somewhere. Where you register depends on what object is responsible for moving myTextField. In my project, the field's superview is responsible, and since I load my UI from a nib, I do it in the superview's awakeFromNib:

- (void)awakeFromNib
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillShowNotification object:nil];
}

如果您使用 UIViewController 要移动字段,你可能想要在 viewWillAppear:animated:

If you use a UIViewController to move the field around, you'll probably want to do it in viewWillAppear:animated:.

您应该在 dealloc 中取消注册viewWillDisappear:animated:

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

当然,棘手的一点是在 keyboardWillHideOrShow中: 方法。首先,我从通知中提取动画参数:

Of course the tricky bit is in the keyboardWillHideOrShow: method. First I extract the animation parameters from the notification:

- (void)keyboardWillHideOrShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

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

keyboardFrame 位于全局坐标系中。我需要将帧转换为与 myTextField.frame 相同的坐标系,并且 myTextField.frame 位于坐标中系统 myTextField.superview

The keyboardFrame is in the global coordinate system. I need to convert the frame to the same coordinate system as myTextField.frame, and myTextField.frame is in the coordinate system of myTextField.superview:

    CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];

接下来,我计算我想要的框架 myTextField 搬到。新框架的下边缘应该等于键盘框架的上边缘:

Next, I compute the frame that I want myTextField to move to. The bottom edge of the new frame should be equal to the top edge of the keyboard's frame:

    CGRect newTextFieldFrame = self.myTextField.frame;
    newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;

最后,我将 myTextField 动画为新的框架,使用键盘使用的相同动画参数:

Finally, I animate myTextField to its new frame, using the same animation parameters that the keyboard is using:

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.myTextField.frame = newTextFieldFrame;
    } completion:nil];
}

这里全部放在一起:

- (void)keyboardWillHideOrShow:(NSNotification *)note
{
    NSDictionary *userInfo = note.userInfo;
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

    CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];

    CGRect newTextFieldFrame = self.myTextField.frame;
    newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.myTextField.frame = newTextFieldFrame;
    } completion:nil];
}

这篇关于在eventFirstResponder或resignFirstResponder的情况下,将对象保持在键盘顶部?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆