UIScrollView无法接收滚动操作

时间:2012-06-25 15:09:02

标签: objective-c ios uiscrollview

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

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

查看控制器     UIScrollView中          的UIView              按钮/文本框/标签/ 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;
}

如果这是一个让我不断滑倒的简单错误,我不会感到惊讶,但这种可访问性功能在应用程序中真的很棒。任何帮助都会非常感激,甚至其他可能的解决方案我想解决的问题也会很棒。

1 个答案:

答案 0 :(得分:0)

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

这是UIResponder class reference。它列出了视图控制器自动继承的所有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];
           }
       }
    }
}