1

在我正在开发的应用程序中,我现在的目标是在键盘显示时滚动内容,并允许用户在显示时滚动。我尝试了一些不同的解决方案,但还没有一个能够实现这一点。

我在应用程序中使用故事板,这是视图控制器中的元素层次结构:

视图控制器 UIScrollView UIView Buttons/textfields/labels/UIPickerView

我首先将 UIScrollView 的内容大小设置为与其中包含所有表单元素的视图大小相同。当这不起作用时,我尝试过度夸大内容的高度,手动将内容大小设置为 320 x 2000。同样,这不起作用。我在滚动视图上也将用户交互启用设置为 YES。这是我此时的代码。

CGSize contentSize = CGSizeMake(320, 2000);
[self.scrollView setContentSize:contentSize];

在滚动视图中,我有一个按钮,它位于整个表单的后面,如果用户触摸它的外部,它可以关闭键盘。我禁用了它以查看它是否可能是阻止它滚动的事件冲突。再次,没有工作。

-(IBAction)closeKeyboard:(id)sender
{
    if(![self isFirstResponder]){
        [self.view endEditing:YES];
    }
}

我什至设置了一些观察者来查看键盘是否即将出现或消失。观察者将根据键盘当前所在的位置调整滚动视图的高度,而不是内容大小,仅调整滚动视图本身。所以在这一点上,滚动视图中的内容会比滚动视图本身高得多,但仍然没有滚动发生。

这是我的观察者的代码:

// adjust view based on keyboard
- (void)keyboardWillHide:(NSNotification *)n
{
    NSDictionary* userInfo = [n userInfo];

    // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;


    // resize the scrollview
    CGRect viewFrame = self.view.frame;
    // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.
    //viewFrame.size.height += keyboardSize.height;

    CGRect scrollRect = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.width, viewFrame.size.height + keyboardSize.height + 100);

    [UIScrollView beginAnimations:nil context:NULL];
     [UIScrollView setAnimationBeginsFromCurrentState:YES];
    [UIScrollView setAnimationDuration:0.3];
    [self.scrollView setFrame:scrollRect];
    self.scrollView.userInteractionEnabled = YES;
    [UIScrollView commitAnimations];

    keyboardShowing = false;
}

- (void)keyboardWillShow:(NSNotification *)n
{
    // This is an ivar I'm using to ensure that we do not do the frame size adjustment on    the UIScrollView if the keyboard is already shown.  This can happen if the user, after fixing editing a UITextField, scrolls the resized UIScrollView to another UITextField and attempts to edit the next UITextField.  If we were to resize the UIScrollView again, it would be disastrous.  NOTE: The keyboard notification will fire even when the keyboard is already shown.
   if (keyboardShowing) {
      return;
   }

   NSDictionary* userInfo = [n userInfo];

   // get the size of the keyboard
    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

   // resize the noteView
   CGRect viewFrame = self.view.frame;
   // I'm also subtracting a constant kTabBarHeight because my UIScrollView was offset by the UITabBar so really only the portion of the keyboard that is leftover pass the UITabBar is obscuring my UIScrollView.

   CGRect scrollRect = CGRectMake(viewFrame.origin.x, viewFrame.origin.y, viewFrame.size.width, viewFrame.size.height - keyboardSize.height - 100);
   //scrollView.frame.size.height -= keyboardSize.height;

    //viewFrame.size.height -= keyboardSize.height;
    [UIScrollView beginAnimations:nil context:NULL];
    [UIScrollView setAnimationBeginsFromCurrentState:YES];
    [UIScrollView setAnimationDuration:0.3];
    [self.scrollView setFrame:scrollRect];
    self.scrollView.userInteractionEnabled = YES;
    [UIScrollView commitAnimations];

    keyboardShowing = YES;
}

如果这是我一直在思考的那些简单错误之一,我不会感到惊讶,但是这种可访问性功能在应用程序中会非常好。任何帮助将不胜感激,甚至我试图解决的问题的其他可能解决方案也将很棒。

4

1 回答 1

0

看起来您正在 IB 中使用手势识别器来检测点击外部事件。因为此识别器位于层次结构的最高视图中,所以它会覆盖滚动视图的检测器。您可能需要稍微更改它,具体取决于您希望能够点击哪些区域来关闭键盘。

这是UIResponder 类参考。它列出了视图控制器自动继承的所有 UIResponder 事件。可以解决您的问题的方法是将您的 UIScrollView 子类化并向其添加键盘关闭代码。另外,请确保将其设置为第一响应者。

最终有效的代码:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{
    mouseSwiped = NO;
    UITouch *touch = [touches anyObject];
    if ([touch tapcount] == 1)
       for(UIView *view in self.view.subviews){
           if([view isKindOfClass:[UITextField class]]){
               [view resignFirstResponder];
           }
       }
    }
}
于 2012-06-25T17:43:47.223 回答