键盘显示时在iPad上滑动UITextField

时间:2011-05-24 14:39:06

标签: iphone objective-c ipad

我有来自Cocoa with Love的代码,当键盘出现时滚动UITextField,这样键盘就不会覆盖UITextField。

以下是代码:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    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;

    // Issue is that numerator isn't big enough for bottom 3rd of the screen

    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;

    NSLog(@"Midline: %g Fraction: %g / %g", midline, numerator, denominator);

    if (heightFraction < 0.0)
    {
        heightFraction = 0.0;
    }
    else if (heightFraction > 1.0)
    {
        heightFraction = 1.0;
    }

    UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];
    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];
}

出于调试目的,我输出中线等,看看发生了什么。这是从上到下的标签。您可以看到分子下面的第6个变为负数,因为为其父视图转换的UITExtField.size.height是一个较小的数字。我无法弄清楚为什么这个数字会是负面的。当你沿着视线走时,高度应该像所有其他高度一样。

2011-05-24 09:36:08.600 Baby Bloom [27794:207] Midline = 246 + 0.5 * 167

2011-05-24 09:36:08.601 Baby Bloom [27794:207]中线:329.5分数:22.3 / 409.6

2011-05-24 09:36:09.535 Baby Bloom [27794:207] Midline = 246 + 0.5 * 167

2011-05-24 09:36:09.536 Baby Bloom [27794:207]中线:329.5分数:22.3 / 409.6

2011-05-24 09:36:09.929 Baby Bloom [27794:207] Midline = 246 + 0.5 * 246

2011-05-24 09:36:09.930 Baby Bloom [27794:207]中线:369分数:61.8 / 409.6

2011-05-24 09:36:10.313 Baby Bloom [27794:207] Midline = 246 + 0.5 * 246

2011-05-24 09:36:10.314 Baby Bloom [27794:207]中线:369分数:61.8 / 409.6

2011-05-24 09:36:10.793 Baby Bloom [27794:207] Midline = 246 + 0.5 * 97

2011-05-24 09:36:10.794 Baby Bloom [27794:207]中线:294.5分数:-12.7 / 409.6

2011-05-24 09:36:11.785 Baby Bloom [27794:207] Midline = 246 + 0.5 * 148

2011-05-24 09:36:11.786 Baby Bloom [27794:207]中线:320分数:12.8 / 409.6

2 个答案:

答案 0 :(得分:2)

事实证明,当在iPad上的横向时,它会切换原点(x现在是y,宽度现在是高度。

以下是使其有效的代码:

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
    CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];

    float origin;
    float textFieldHeight;
    float viewOrigin;
    float viewHeight;

    UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];


    if (orientation == UIInterfaceOrientationPortrait ||
        orientation == UIInterfaceOrientationPortraitUpsideDown)
    {
        textFieldHeight = textFieldRect.size.height;
        origin = textFieldRect.origin.y;
        viewOrigin = viewRect.origin.y;
        viewHeight = viewRect.size.height;
    }
    else
    {
        textFieldHeight = textFieldRect.size.width;
        viewOrigin = viewRect.origin.x;
        viewHeight = viewRect.size.width;
        origin = viewHeight - textFieldRect.origin.x;
    }


    CGFloat midline = origin + 0.5 * textFieldHeight;

    // Take the current middle y location of the textfield
    // If it is in the top 20% of the view don't move it
    // If it is in the middle 60% move it by a fraction of the keyboard size
    // If it is in the bottom 20% move it by the whole size of the keyboard


    CGFloat numerator = midline - viewOrigin - MINIMUM_SCROLL_FRACTION * viewHeight;

    CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewHeight;

    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;

    //NSLog(@"Denom: %g", denominator);
    //NSLog(@"Distance: %g", animatedDistance);

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

    [self.view setFrame:viewFrame];

    [UIView commitAnimations];
}

答案 1 :(得分:1)

origin = viewHeight - textFieldRect.origin.x;

我认为你不需要这个,因为它会产生不正确的字段原点和非常大的中间值,它们在不需要的地方执行滚动。 所以通常你应该使用x origin作为y。

origin = textFieldRect.origin.x;