objective-c - 点击键盘上方移动文本字段的逻辑

标签 objective-c ios xcode uitextfield

现在,我已经有了在您开始编辑时将文本字段移动到键盘上方的基本代码。但是,文本字段的大小因设备和方向而异。所以,我写了一个粗略的方法,它不会一直保持在键盘正上方,而是在你旋转它时会进一步上升,所以它看起来不像我想要的那样专业。

我的问题的基本含义是,是否存在基于设备和方向获取键盘大小并自动使用该值并希望比这更快的逻辑。

如果这是最好的方法,请告诉我。否则,请提供输入。这是我的代码。 (这里只是上移代码,不是下移代码,以免占用太多篇幅)

- (void)textFieldDidBeginEditing:(UITextField *)textField { 

    //Get Device Type
    NSString *deviceType = [[UIDevice currentDevice] model];

    //Animate Text Field
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDuration:0.4];
    [UIView setAnimationBeginsFromCurrentState:YES];

    if ([deviceType isEqualToString:@"iPhone"]) {

        //Size For iPhone
        googleBar.frame = CGRectMake(googleBar.frame.origin.x - 62.0, (googleBar.frame.origin.y - 210.0), googleBar.frame.size.width + 120.0, googleBar.frame.size.height);

    } else if ([deviceType isEqualToString:@"iPad"]) {

        //Size for iPad
        googleBar.frame = CGRectMake(googleBar.frame.origin.x - 62.0, (googleBar.frame.origin.y - 320.0), googleBar.frame.size.width + 120.0, googleBar.frame.size.height);

    } else if ([deviceType isEqualToString:@"iPod touch"]) {

        //Size For iPod Touch
        googleBar.frame = CGRectMake(googleBar.frame.origin.x - 62.0, (googleBar.frame.origin.y - 210.0), googleBar.frame.size.width + 120.0, googleBar.frame.size.height);

    } 

    [UIView commitAnimations];

} 

最佳答案

您真正想要做的是观察 UIKeyboard(Did|Will)(Show|Hide) 通知。它们在 userInfo 字典中包含开始和结束帧,以及正确的动画曲线和持续时间。

因此,在观察到此通知后,当它发布时,根据提供的动画提示,根据通知中传递的框架大小移动您的文本字段。

您可以在 UIWindow 类引用的“通知”部分看到更多信息:https://developer.apple.com/library/ios/#documentation/uikit/reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html

下面是一个示例 View Controller 实现。这个 View Controller 的 Nib 只是一个单独的文本字段,有一个导出连接到它,文本字段的委托(delegate)设置为 View Controller 。

@interface ViewController ()

- (void)viewControllerInit;

@end

@implementation ViewController

@synthesize textField;

- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        [self viewControllerInit];
    }
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
    {
        [self viewControllerInit];
    }
    return self;
}


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


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


#pragma mark - Notification Handlers

- (void)keyboardWillShow:(NSNotification *)notification
{
    // I'll try to make my text field 20 pixels above the top of the keyboard
    // To do this first we need to find out where the keyboard will be.

    NSValue *keyboardEndFrameValue = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardEndFrame = [keyboardEndFrameValue CGRectValue];

    // When we move the textField up, we want to match the animation duration and curve that
    // the keyboard displays. So we get those values out now

    NSNumber *animationDurationNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration = [animationDurationNumber doubleValue];

    NSNumber *animationCurveNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    UIViewAnimationCurve animationCurve = [animationCurveNumber intValue];

    // UIView's block-based animation methods anticipate not a UIVieAnimationCurve but a UIViewAnimationOptions.
    // We shift it according to the docs to get this curve.

    UIViewAnimationOptions animationOptions = animationCurve << 16;


    // Now we set up our animation block.
    [UIView animateWithDuration:animationDuration 
                          delay:0.0 
                        options:animationOptions 
                     animations:^{
                         // Now we just animate the text field up an amount according to the keyboard's height,
                         // as we mentioned above.
                        CGRect textFieldFrame = self.textField.frame;
                        textFieldFrame.origin.y = keyboardEndFrame.origin.y - textFieldFrame.size.height - 40; //I don't think the keyboard takes into account the status bar
                        self.textField.frame = textFieldFrame;
                     } 
                     completion:^(BOOL finished) {}];

}


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

    NSNumber *animationDurationNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration = [animationDurationNumber doubleValue];

    NSNumber *animationCurveNumber = [[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    UIViewAnimationCurve animationCurve = [animationCurveNumber intValue];
    UIViewAnimationOptions animationOptions = animationCurve << 16;

    [UIView animateWithDuration:animationDuration 
                          delay:0.0 
                        options:animationOptions 
                     animations:^{
                         self.textField.frame = CGRectMake(20, 409, 280, 31); //just some hard coded value
                     } 
                     completion:^(BOOL finished) {}];

}
#pragma mark - View lifecycle

- (void)viewDidUnload
{
    [self setTextField:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self.textField resignFirstResponder];
    return YES;
}

@end

关于objective-c - 点击键盘上方移动文本字段的逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9135248/

相关文章:

ios - 应用检查更新

objective-c - Cocoa - 捕获特定事件

iphone - 为iPhone应用程序实现旁白

ios - 在Swift中将逗号和十进制后的零值添加到千位数后的字符串中

ios - SceneKit NSNode 拆分部分

objective-c - 使用 CIFilter 和 CISpotColor 正确过滤 NSImage/CIImage

ios - 带有 OpenSSL 的 Objective-C - 无法设置 RSA key

ios - 为什么 Xcode 5 一直给我这些错误?

swift - 除非绑定(bind)到 Xcode,否则推送通知无法完全正常工作

swift - 为什么对象只有从 NSObject 继承时才会变成 NSZombie?