如何在方向更改时将ScrollView定位在键盘后面

时间:2011-06-16 11:26:29

标签: iphone cocoa-touch uiscrollview keyboard orientation

我有一个UIScrollView,用于在键盘启动时启用滚动功能。在纵向模式下滚动视图的定位很好;我已将其定位在Interface Builder中,并在我的代码中设置contentSize ...

CGSize scrollContentSize = CGSizeMake(360, 221);
self.scrollView.contentSize = scrollContentSize;

但是,我正在努力弄清楚如何改变scrollview的位置,以便在方向更改为横向(和背面)时有效。我是否需要在Interface Builder中将其放置在横向(?)中,然后根据方向更改我的代码中的内容大小?

编辑: 我得到键盘大小如下,并改变内容大小。这在我移动到肖像时有效,但在横向模式下框架的位置略有错误。

 (void)keyboardWillShow:(NSNotification *)n{

    if (keyboardIsShown) {
    return;
    }

    NSDictionary* userInfo = [n userInfo];

    CGRect _keyboardEndFrame;
    [[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
    CGFloat _keyboardHeight;
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
    _keyboardHeight = _keyboardEndFrame.size.height;
    }
    else {
        _keyboardHeight = _keyboardEndFrame.size.width;
    }

    // resize the noteView
    CGRect viewFrame = self.scrollView.frame;
     viewFrame.size.height -= _keyboardHeight;

    if (UIDeviceOrientationIsPortrait(orientation)){
        CGSize scrollContentSize = CGSizeMake(360, 221);
        self.scrollView.contentSize = scrollContentSize;
    }
    else if (UIDeviceOrientationIsLandscape(orientation)){
        CGSize scrollContentSize = CGSizeMake(520, 275);
        self.scrollView.contentSize = scrollContentSize;
    }

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3];
    [self.scrollView setFrame:viewFrame];
    [UIView commitAnimations];

    keyboardIsShown = YES;
}

2 个答案:

答案 0 :(得分:5)

您要做的是弄清楚键盘顶部相对于包含scrollView的视图的位置。幸运的是,UIView中有一个名为convertRect:fromView:的函数,它将从一个坐标系中获取帧并将其映射到另一个坐标系。在您的情况下,您知道键盘相对于主窗口的框架,但想知道键盘顶部相对于包含scrollView的视图的位置。一旦知道键盘顶部与视图相交的位置,就可以修改scrollView的高度以适应。

下面是我使用的一段代码,我在网上找到了一些代码,并且不予以赞扬。在视图控制器中,您希望收到键盘显示和隐藏事件的通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];

然后像这样实施keyboardWillShow:keyboardWillHide:

// When the keyboard shows resize self.textView to touch the top of the keyboard.
-(void)keyboardWillShow:(NSNotification *)_notification {
    NSDictionary  *userInfo = [_notification userInfo];

    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardEndFrame;
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];

        // Here we figure out where the keyboard overlaps with self.view
        // self.view contains self.textView
    CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame fromView:nil];
    CGFloat textViewWidth = self.view.frame.size.width;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];
    self.textView.frame = CGRectMake(0, 0, textViewWidth, keyboardFrame.origin.y);
    [UIView commitAnimations];
}

// When the keyboard hides return self.textView to fullscreen
-(void)keyboardWillHide:(NSNotification *)_notification {
    NSDictionary  *userInfo = [_notification userInfo];

    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardEndFrame;
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];
    self.textView.frame = self.view.frame;
    [UIView commitAnimations];  
}

该片段包含一些额外的内容,可以与键盘动画同步动画转场。

在此代码段中,我使用了self.textView,您可能希望将其更改为self.scrollView。这段代码的优点在于它适用于所有方向和iPad。看看代码,希望它是自我解释的。

答案 1 :(得分:0)

使用此方法检查方向&根据方向更改内容scrollView的大小

  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation