【问题标题】:scrollViewWillEndDragging:withVelocity:targetContentOffset: not working on the edges of a UISCrollViewscrollViewWillEndDragging:withVelocity:targetContentOffset: 在 UISCrollView 的边缘不起作用
【发布时间】:2012-06-08 11:23:41
【问题描述】:

我正在尝试实现一个可滚动的自定义标签栏,并且在每个标签栏项目上都有分页。为此,我正在使用委托 scrollViewWillEndDragging:withVelocity:targetContentOffset: 它完美地解决了一个问题。

我的分页工作方式是,如果 contentOffset 靠近正确的项目,则 targetContentOffset 会更改为该项目的偏移量。左侧也一样。

问题是,每当我在第一个项目的左半部分和最后一个项目的右侧(滚动视图水平工作)时,它应该转到 ContentOffset 0 和最右边项目的内容偏移量(减去屏幕上的那些),但它没有。

我检查了调试器,targetContentOffset->x 确实为 0(在第一种情况下 - 最左边的项目的左侧)。所以问题是 UIScrollView 没有在那里滚动。我迷路了。

这是我实现的委托:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                 withVelocity:(CGPoint)velocity
          targetContentOffset:(inout CGPoint *)targetContentOffset{
     NSInteger index = lrintf(targetContentOffset->x/self.tabWidth);
     targetContentOffset->x = index * self.tabWidth;
}

这是解释我想要做什么的图表。

|-------|-------|-------|-------|-------|-------|-------|
|       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |
|_______|_______|_______|_______|_______|_______|_______|

        |_______________________________________|
         where it is and i scroll it to the left

   <----|

   |_______________________________________|
              where it would stop

|_______________________________________|
        where i want it to stop

【问题讨论】:

    标签: ios uiscrollview ios5 uiscrollviewdelegate


    【解决方案1】:

    在 iOS 6.0 上已修复问题。

    现在它可以正常工作了。

    【讨论】:

      【解决方案2】:

      我尝试按照 Big Papoo 的建议将最终偏移设置为稍微偏离零或内容大小,但注意到这消除了过度滚动反弹。我对此的解决方案是检查原始 targetContentOffset 以查看它是否等于零或 contentSize,如果是则将其保留:

      - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
      
          float expectedOffset = targetContentOffset->x;
          if (expectedOffset == 0 || expectedOffset == scrollView.contentSize.width) return; // Scroll view will bounce so leave the targetContentOffset.
      
          float targetOffset = [self roundedOffset:expectedOffset]; // Round your offset.
      
          // Adjust the offset to make sure it works.
          if (targetOffset == 0) targetOffset = 1;
          else if (targetOffset == SCROLLVIEW_WIDTH) targetOffset = SCROLLVIEW_WIDTH - 1;
      
          targetContentOffset->x = targetOffset;
      }
      

      您当然可以使用scrollViewDidEndDecelerating: 将滚动视图移动 1 点。

      【讨论】:

        【解决方案3】:

        如果您使用的是水平表格视图,那么在您的 scrollViewWillEndDragging:withVelocity:targetContentOffset: 函数中,您可以调用:

        [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:<index> inSection:<section>] atScrollPosition:UITableViewScrollPositionTop animated:YES];
        

        我发现这比尝试在水平表视图中操作 targetContentOffset->y 要好得多。

        【讨论】:

          【解决方案4】:

          这似乎是一个已知问题。经过一些调查并与其他人交谈后,有人认为这可能是一个错误,结果证明是正确的。我向 Apple 报告了它,它是否被标记为重复但仍处于打开状态。只为有同样问题的人解答。我像 Big Papoo 建议的那样解决它,通过使用接近我想要的偏移量(0.1 似乎可以做到)。右端也一样。

          【讨论】:

          • 我也遇到了这个问题。您是否有机会发布 Apple 错误 ID 号——或者更好的是,一个指向 OpenRadar 条目的链接——以帮助我自己,可能还有其他人,发布重复的错误报告? (众所周知,Apple 根据收到的报告数量优先修复错误。)
          • 当然。它是 10255505 的副本,但在 OpenRadar 中似乎不存在。不管怎样,它现在似乎已经关闭了,但我不知道他们是否会发布修复程序。
          【解决方案5】:

          我发现了 2 个您可以调查的未记录行为: - 将零设置为最终偏移不起作用,我建议设置 1 或大于零的任何值(0.5 可能有效,未经测试) - 您最好检查速度符号并计算您的最终偏移量,使其位于用户移除手指的当前点的左侧或右侧。不要试图让滚动在另一侧向后移动。

          【讨论】:

          • 非常感谢您的回答。你说得对。我也进行了调查并与其他人交谈,发现这是一个错误。只是忘了回答我自己的问题,抱歉(如果您想了解更多详细信息,请查看)。像 0.1 这样的偏移量似乎可以做到这一点。无论如何,非常感谢。
          猜你喜欢
          • 1970-01-01
          • 2018-06-21
          • 2014-10-24
          • 1970-01-01
          • 2020-08-25
          • 2017-11-20
          • 1970-01-01
          • 1970-01-01
          • 2018-04-29
          相关资源
          最近更新 更多