出现键盘时调整视图大小 (iOS)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16043371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:12:15  来源:igfitidea点击:

Resize a view when a keyboard appears (iOS)

iphoneiosipadkeyboardlandscape-portrait

提问by bkocik

I realize there are many similar solutions, such as TPKeyboardAvoiding, Apple's famous solution, and various suggestions involving the use of UIScrollView. In my case, I need to resize a view to accommodate the keyboard rather than scroll or move it. This solutioncomes closest to what I'm trying to achieve, so it was my basis. However I'm having an issue making things work in landscape mode. My method that resizes the view when the keyboard appears is this:

我意识到有很多类似的解决方案,例如TPKeyboardAvoidingApple 著名的解决方案,以及涉及使用 UIScrollView 的各种建议。就我而言,我需要调整视图的大小以适应键盘,而不是滚动或移动它。这个解决方案最接近我想要实现的目标,所以它是我的基础。但是我在横向模式下工作时遇到了问题。我在键盘出现时调整视图大小的方法是:

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

    CGRect keyboardFrame = [[self textField].superview convertRect:[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
    CGRect statusBarFrame = [[self textField].superview convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil];

    CGRect bounds = [self textField].superview.bounds;    
    CGRect newFrame = CGRectMake(0.0, 0.0, bounds.size.width, keyboardFrame.origin.y + statusBarFrame.size.height);
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        [self textField].superview.frame = newFrame;
    } completion:nil];
}

This works perfectly in portrait mode.

这在纵向模式下非常有效。

enter image description here

在此处输入图片说明

However, in landscape mode, the view resizes from left-to-right or right-to-left depending upon in which direction the device was rotated, rather than from the bottom up.

但是,在横向模式下,视图会根据设备旋转的方向从左到右或从右到左调整大小,而不是从下到上。

enter image description here

在此处输入图片说明

Clearly there is something wrong with how I'm using coordinates, and some frame of reference isn't what I think it is when in landscape mode, but I'm having a heck of a time sorting out how to resolve it. I've tried converting all kinds of things with -convertRect: but nothing I'm trying is getting me anywhere.

显然,我使用坐标的方式有问题,并且某些参考系在横向模式下并不是我认为的那样,但是我花了很长时间来整理如何解决它。我试过用 -convertRect: 转换各种各样的东西,但我没有尝试让我去任何地方。

I'm really hoping someone who's less confused by all these rectangles and how they change when orientation changes can spot what I'm doing wrong and what I need to do to get this right. For reference, I've created a projectshowing the simplest case that reproduces the problem I'm having.

我真的希望那些对所有这些矩形以及当方向改变时它们如何变化不那么困惑的人能够发现我做错了什么以及我需要做什么才能做到这一点。作为参考,我创建了一个项目,展示了重现我遇到的问题的最简单案例。

回答by Vitaly Berg

I do not advise you to resize root view for your view controller, you can create contentView and add to view of view controller. You can change size of this contentView as below (I don't use autolayouting):

我不建议您调整视图控制器的根视图大小,您可以创建 contentView 并添加到视图控制器的视图中。您可以如下更改此 contentView 的大小(我不使用自动布局):

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

    CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
    } completion:nil];
}

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

    CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil];

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
        self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y);
    } completion:nil];
}

回答by xiongemi

Vitaliy B's answer in swift. I got a view called templateHeaderContentView, I created a function and configured the view height there. You use your own view and change the height accordingly there.

Vitaliy B 的回答很快。我有一个名为 templateHeaderContentView 的视图,我创建了一个函数并在那里配置了视图高度。您使用自己的视图并在那里相应地更改高度。

func keyboardWillShow(notification: NSNotification) {
    keyboardShowOrHide(notification)
}

func keyboardWillHide(notification: NSNotification) {
    keyboardShowOrHide(notification)
}

private func keyboardShowOrHide(notification: NSNotification) {
    guard let userInfo = notification.userInfo else {return}
    guard let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]else { return }
    guard let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] else { return }
    guard let keyboardFrameEnd = userInfo[UIKeyboardFrameEndUserInfoKey] else { return }

    let curveOption = UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16))
    let keyboardFrameEndRectFromView = view.convertRect(keyboardFrameEnd.CGRectValue, fromView: nil)
    UIView.animateWithDuration(duration.doubleValue ?? 1.0,
        delay: 0,
        options: [curveOption, .BeginFromCurrentState],
        animations: { () -> Void in
            self.templateHeaderContentView.configureView(keyboardFrameEndRectFromView.origin.y)
        }, completion: nil)
}

回答by Patel Jigar

i had done it hope this code will be helpfull for u.

我已经做到了,希望此代码对您有所帮助。

- (void)viewWillAppear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

- (void)keyboardWillShow:(NSNotification*)notification
{
    [self moveControls:notification up:YES];
}

- (void)keyboardWillBeHidden:(NSNotification*)notification
{
    [self moveControls:notification up:NO];
}

- (void)moveControls:(NSNotification*)notification up:(BOOL)up
{
    NSDictionary* userInfo = [notification userInfo];
    CGRect newFrame = [self getNewControlsFrame:userInfo up:up];

    [self animateControls:userInfo withFrame:newFrame];
}

- (CGRect)getNewControlsFrame:(NSDictionary*)userInfo up:(BOOL)up
{
    CGRect kbFrame = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    kbFrame = [self.view convertRect:kbFrame fromView:nil];

    CGRect newFrame = self.view.frame;
    newFrame.origin.y += kbFrame.size.height * (up ? -1 : 1);

    return newFrame;
}

- (void)animateControls:(NSDictionary*)userInfo withFrame:(CGRect)newFrame
{
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];

    [UIView animateWithDuration:duration
                          delay:0
                        options:animationOptionsWithCurve(animationCurve)
                     animations:^{
                         self.view.frame = newFrame;
                     }
                     completion:^(BOOL finished){}];
}

static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve)
{
    return (UIViewAnimationOptions)curve << 16;
}

回答by nivrit gupta iphone

Try this methods. Edit it according to your requirement.

试试这个方法。根据您的要求编辑它。

#define kOFFSET_FOR_KEYBOARD 280.0

- (void)keyboardWillHide:(NSNotification *)notif {
    [self setViewMoveUp:NO];
}


- (void)keyboardWillShow:(NSNotification *)notif{
    [self setViewMoveUp:YES];
}


- (void)textFieldDidBeginEditing:(UITextField *)textField {
    stayup = YES;
    [self setViewMoveUp:YES];
}


- (void)textFieldDidEndEditing:(UITextField *)textField {
    stayup = NO;
    [self setViewMoveUp:NO];
}

//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMoveUp:(BOOL)moveUp
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3]; // if you want to slide up the view
    [UIView setAnimationBeginsFromCurrentState:YES];

    CGRect rect = self.view.frame;
    if (moveUp)
    {
        // 1. move the view's origin up so that the text field that will be hidden come above the keyboard 
        // 2. increase the size of the view so that the area behind the keyboard is covered up.

        if (rect.origin.y == 0 ) {
            rect.origin.y -= kOFFSET_FOR_KEYBOARD;
            //rect.size.height += kOFFSET_FOR_KEYBOARD;
        }

    }
    else
    {
        if (stayup == NO) {
            rect.origin.y += kOFFSET_FOR_KEYBOARD;
            //rect.size.height -= kOFFSET_FOR_KEYBOARD;
        }
    }
    self.view.frame = rect; 
    [UIView commitAnimations];
}