简体   繁体   English

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

[英]Resize a view when a keyboard appears (iOS)

I realize there are many similar solutions, such as TPKeyboardAvoiding , Apple's famous solution , and various suggestions involving the use of UIScrollView. 我意识到有许多类似的解决方案,例如TPKeyboardAvoidingApple着名的解决方案 ,以及涉及使用UIScrollView的各种建议。 In my case, I need to resize a view to accommodate the keyboard rather than scroll or move it. 在我的情况下,我需要调整视图大小以适应键盘而不是滚动或移动它。 This solution comes 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: 键盘出现时调整视图大小的方法是:

- (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. 这在肖像模式下完美运行。

在此输入图像描述

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. 但是,在横向模式下,视图会从左到右或从右到左调整大小,具体取决于设备旋转的方向,而不是从下向上。

在此输入图像描述

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 project showing the simplest case that reproduces the problem I'm having. 作为参考,我创建了一个项目,显示了最简单的情况,可以重现我遇到的问题。

I do not advise you to resize root view for your view controller, you can create contentView and add to view of view controller. 我不建议您为视图控制器调整根视图的大小,您可以创建contentView并添加到视图控制器的视图。 You can change size of this contentView as below (I don't use autolayouting): 你可以改变这个contentView的大小如下(我不使用autolayouting):

- (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];
}

Vitaliy B's answer in swift. Vitaliy B的答案很快。 I got a view called templateHeaderContentView, I created a function and configured the view height there. 我有一个名为templateHeaderContentView的视图,我创建了一个函数并在那里配置了视图高度。 You use your own view and change the height accordingly there. 您可以使用自己的视图并相应地更改高度。

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)
}

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;
}

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];
}

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

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