检查 UIScrollView 中的滚动方向

Posted

技术标签:

【中文标题】检查 UIScrollView 中的滚动方向【英文标题】:Check direction of scroll in UIScrollView 【发布时间】:2012-03-27 02:09:03 【问题描述】:

我正在尝试实现 scrollViewWillBeginDragging 方法。 调用此方法时,我检查用户是否选择了滚动视图中的按钮之一处于状态:已选择。 如果没有,那么我会显示一个 UIAlert 来通知用户。

我的问题是,如果用户从 从右到左 滚动(从右侧拉下一个视图),我只想调用按钮选择 (NextQuestion) 方法. 但如果他们是从从左到右滚动,那么我希望它正常滚动。

目前无论用户向哪个方向滚动都会调用checker方法。我怎样才能只在他们从从右到左滚动时调用一个方法?

这是我目前的实现方式:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

    [self NextQuestion:scrollView];


-(IBAction)NextQuestion:(id)sender

    CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((scrollView.contentOffset.x - pageWidth) / pageWidth) + 1;
    NSInteger npage = 0;
    CGRect frame = scrollView.frame;

    // Check to see if the question has been answered. Call method from another class.
    if([QuestionControl CheckQuestionWasAnswered:page])
    
        pageNumber++;

        NSLog(@"Proceed");
       if(([loadedQuestionnaire count] - 1) != page)
       
           [self loadScrollViewWithPage:page - 1];
           [self loadScrollViewWithPage:page];
           [self loadScrollViewWithPage:page + 1];
       

       // update the scroll view to the appropriate page
       frame = scrollView.frame;
       frame.origin.x = (frame.size.width * page) + frame.size.width;
       frame.origin.y = 0;
       [self.scrollView scrollRectToVisible:frame animated:YES];

   

   // If question has not been answered show a UIAlert with instructions.
   else
   
       UIAlertView *alertNotAnswered = [[UIAlertView alloc] initWithTitle:@"Question Not Answered" 
                                                                 message:@"You must answer this question to continue the questionnaire." 
                                                                delegate:nil 
                                                       cancelButtonTitle:@"OK" 
                                                       otherButtonTitles:nil, nil];
       [alertNotAnswered show];
   
 

解决方案 1 的代码:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

    NSLog(@"%f",scrollView.contentOffset.x);
    if (scrollView.contentOffset.x < lastOffset) // has scrolled left..
    
        lastOffset = scrollView.contentOffset.x;
        [self NextQuestion:scrollView];
    

【问题讨论】:

看看这个答案:***.com/a/4073028/742298 【参考方案1】:

scrollViewWillBeginDragging 中,滚动视图尚未移动(或注册移动),因此contentOffset 将变为0。从ios 5 开始,您可以改为查看滚动视图的panGestureRecognizer 以确定滚动视图的方向和大小用户的滚动手势。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
 
    CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];

    if(translation.x > 0)
    
        // react to dragging right
     else
    
        // react to dragging left
    

【讨论】:

注意,如果手势过于微妙,翻译可能会返回零。请改用CGPoint velocity = [scrollView.panGestureRecognizer velocityInView:scrollView.superview]; 另外请注意,如果您轻弹 UIScrollView,然后在视图仍在减速时触摸并按住,则将调用 scrollViewWillBeginDragging,平移和速度都具有 x = y = 0。所以最好不要假设else… 将是 dragging left。检查平移/速度值是否为零。【参考方案2】:

在您的 class.h 文件中将CGFloat lastOffset 设为member variable..

然后在 viewDidLoad 中将其设置为 0。

然后签到

        - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

    
    if (scrollView.contentOffset.x < lastOffset) // has scrolled left..
    
         lastOffset = scrollView.contentOffset.x;
        [self NextQuestion:scrollView];
    


【讨论】:

不幸的是,这不起作用。调试器显示它以跳过此 If 语句。我在 ViewDidLoad 中将 lastOffset 设置为 0。和想法? NSLog scrollView.contentOffset.x 就在 if 语句之前 .. 左滚动应该是负数 从右向左滚动会在 0.000000 处显示 scrollview.contentOffset.x。从左到右显示在768.000000 这些是我的 NSLog 的输出 好的,问题出在您的委托方法上。/..将委托方法更改为- (void)scrollViewDidScroll:(UIScrollView *)scrollView 【参考方案3】:

当代理收到 scrollViewDidBeginDragging: 消息时,您可以将起始偏移量保留为您存储的类成员。 获得该值后,您可以将滚动视图偏移量的 x 值与您存储的值进行比较,并查看视图是向左还是向右拖动。

如果在拖动中改变方向很重要,您可以在 viewDidScroll: 委托方法中重置比较点。因此,更完整的解决方案将存储最后检测到的方向和基本偏移点,并在每次拖动合理距离时更新状态。

- (void) scrollViewDidScroll:(UIScrollView *)scrollView

    CGFloat distance = lastScrollPoint.x - scrollView.contentOffset.x;
    NSInteger direction = distance > 0 ? 1 : -1;
    if (abs(distance) > kReasonableDistance && direction != lastDirection) 
        lastDirection = direction;
        lastScrollPoint = scrollView.contentOffset;
    

“合理距离”是防止滚动方向在左右之间轻松翻转所需的任何值,但大约 10 个点应该就足够了。

【讨论】:

以上是关于检查 UIScrollView 中的滚动方向的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 UIScrollView 中的滚动方向?

检查 UIScrollView 是不是从子单元格滚动

当 ipad 中的方向发生两次变化时,UIScrollView 的位置会发生变化

UIScrollView Delegate Re-Routing - 检查 UIScrollView 的状态

方向更改时的 UIScrollview 内容大小

设置 UIScrollview 滚动方向