简体   繁体   English

如何在所有界面方向的键盘上方显示文本字段

[英]How to show textfield above keyboard for all interface orientations

In my iPhone app i used the following code to lift the view in order to show the textfield above the keyboard. 在我的iPhone应用程序中,我使用以下代码提升视图以在键盘上方显示文本字段。 My application support all four interface orientations. 我的应用程序支持所有四个界面方向。 I use the following code to lift the view. 我使用以下代码提升视图。 Problem here is that it only works for portrait orientation. 这里的问题是它仅适用于纵向方向。 Is there any way to implement the correct lifting in all four orientations 有什么办法可以在所有四个方向上实现正确的提升

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    UIInterfaceOrientation orientation =    [Globals getUIInterfaceOrientation];//[[UIApplication sharedApplication] statusBarOrientation];
    CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
    CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];   

    CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
    CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
    CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;   
    CGFloat heightFraction = numerator / denominator;

    if (heightFraction < 0.0) {
        heightFraction = 0.0;
    }
    else if (heightFraction > 1.0) {
        heightFraction = 1.0;
    }   
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) 
        animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
    else 
        animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
    CGRect viewFrame = self.view.frame;
    viewFrame.origin.y -= animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    [self.view setFrame:viewFrame];    
    [UIView commitAnimations];  
}

- (void)textFieldDidEndEditing:(UITextField *)textField{
    CGRect viewFrame = self.view.frame;
    viewFrame.origin.y += animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
    [self.view setFrame:viewFrame];    
    [UIView commitAnimations];      
}

The following is how I currently achieve this on all my apps. 以下是我目前在所有应用程序上实现此目标的方式。

The trick here is that although the view is aware of the orientation, the keyboard is not. 这里的技巧是,尽管视图知道方向,但键盘却不知道。 This means in Landscape, the keyboards width is actually its height and visa versa. 这意味着在“风景”中,键盘宽度实际上是其高度,反之亦然。

To modify Apples recommended way of changing the content insets and get it support landscape orientation, I would recommend using the following: 要修改Apple建议的更改内容插图的方式,并使其支持横向,我建议使用以下方法:

// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];
   [[NSNotificationCenter defaultCenter] addObserver:self
             selector:@selector(keyboardWillBeHidden:)
             name:UIKeyboardWillHideNotification object:nil];
}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight ) {
        CGSize origKeySize = keyboardSize;
        keyboardSize.height = origKeySize.width;
        keyboardSize.width = origKeySize.height;
    }
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
    scroller.contentInset = contentInsets;
    scroller.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your application might not need or want this behavior.
    CGRect rect = scroller.frame;
    rect.size.height -= keyboardSize.height;
    NSLog(@"Rect Size Height: %f", rect.size.height);

    if (!CGRectContainsPoint(rect, activeField.frame.origin)) {
        CGPoint point = CGPointMake(0, activeField.frame.origin.y - keyboardSize.height);
        NSLog(@"Point Height: %f", point.y);
        [scroller setContentOffset:point animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent    
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

The part to pay attention to here is the following: 这里需要注意的部分如下:

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight ) {
    CGSize origKeySize = keyboardSize;
    keyboardSize.height = origKeySize.width;
    keyboardSize.width = origKeySize.height;
}

What is does, is detects what orientation the device is in. If it is landscape, it will 'swap' the width and height values of the keyboardSize variable to ensure that the correct values are being used in each orientation. 它的作用是检测设备所处的方向。如果它是横向的,它将“交换” keyboardSize变量的宽度和高度值,以确保在每个方向上都使用正确的值。

Probably you want to use Keyboard notifications shown in this Text and Web Programming Guide for the iOS Document, See Listing 2-1 2-2 2-3 可能要使用此文本和Web编程指南中有关iOS文档的键盘通知,请参见清单2-1 2-2 2-3

You can get keyboard size when receiving the notification. 收到通知时,您可以获取键盘尺寸。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM