【问题标题】:Can't scroll up/down and scroll left/right at the same time on UITableView within a UIScrollView无法在 UIScrollView 内的 UITableView 上同时向上/向下滚动和向左/向右滚动
【发布时间】:2015-09-09 17:52:46
【问题描述】:

第二次更新感谢@Segev 的评论和对另一个主题的引用,我能够改进我的demo 使其基本上可以满足我的需求。但是,它仍然不如 Instagram 的实现那么顺利,我想知道是否有人知道如何改进它以使其更流畅?另外,我注意到有时(在我的演示中),当我向左/向右滑动非常快并且我想切换到向上/向下滑动时,它仍然会继续向左/向右滑动,直到我停止滑动并让它先停下来。

更新:通过从 UIScrollView 继承并从 UIGestureRecognizerDelegate 实现 shouldRecognizeSimultaneouslyWithGestureRecognizer 和 shouldBeRequiredToFailByGestureRecognizer 方法,我能够让表格视图在停止向上/向下滚动后向左/向右滑动。我的想法是,如果用户向上/向下滚动 tableView,则在 shouldRecognizeSimultaneouslyWithGestureRecognizer 中返回 true,然后在 shouldBeRequiredToFailByGestureRecognizer 中返回 true,以使表格视图的向上/向下手势失败。

但我仍然无法弄清楚如何让用户在停止初始向上/向下滚动后向上/向下或向左/向右滚动(并且用户的手指仍在设备上)。

我在这里创建了一个示例项目https://github.com/paulsfds/TableViewsInScrollView。您可以通过在表格视图上向下滑动一次来测试这一点,然后松开手指,在它仍在滚动时,将手指放回以停止滚动。当您的手指仍在表格视图上时,尝试向左/向右滑动,它应该可以工作。但是在这个实现中,如果您尝试多次向下滑动表格视图,它有时会卡住,因为它会认为您正在尝试向左/向右滑动。有什么想法吗?

原文:我有几个 UITableView,它们位于启用了分页的 UIScrollView 中,并设置为让我左右分页,这样一次只能看到一个 UITableView。这是一张图(取自Conflictive scroll on UITableView within UIScrollView

                                 +--visible area--+  ---+
+---------`UIScrollView`---------+---------------+|  --+|
| +-------------+ +-------------+|+-------------+||  -+||
| |      0      | |      1      |||      2      |||   |||
| |`UITableView`| |`UITableView`|||`UITableView`|||  equal height
| |             | |             |||             |||   |||
| +-------------+ +-------------+|+-------------+||  -+||
+--------------------------------+---------------+|  --+| 
                                 +----------------+  ---+

我想要实现的是,如果用户向下滚动表格视图,然后松开手指(并且向下滚动动画仍在发生),用户可以选择左右滑动进入下一个表视图。现在,如果用户向下滚动表格视图,然后抬起手指,而向下滚动动画仍在播放,然后再放回手指以左右滑动,则不允许用户向左和向右滚动对,除非我等待表格视图滚动完全停止,然后左右滑动,否则我无法查看已经可见的表格视图。

TL;DR 基本上我不能同时向上/向下滚动表格并在滚动视图中向左/向右滑动,但我希望能够做到这一点。这方面的一个例子是在 iOS Instagram 应用程序中的“活动”选项卡上。您可以在表格视图仍在滚动时向下滚动然后向右滑动。

【问题讨论】:

  • 您是否考虑过使用 UICollectionView 而不是 UIScrollView?我还没有使用过这种方法,但根据我的经验,我几乎总是能够用 UICollectionView 代替 UIScrollView 的使用(通常更省力。)
  • 我还没有考虑过,但我认为我仍然会遇到 UICollectionView 手势与内部 UITableView 手势冲突的相同问题?
  • 看起来您已经找到了解决方案,根据下面提供的链接,它可能只需要几分钟就可以解决。无论如何,我以前没有真正尝试过。所以我花了几分钟时间来模拟一个collectionView,它有一个包含tableView的单元格子类,配置了dataSources和delegate,并试了一下。所以回答你的问题:不,滑动手势在滚动或分页时不会相互冲突。
  • 在提供我自己的答案后,我刚刚回去阅读了您问题的更新。如果你有时间重新设计你的实现,那么你应该试一试。我对动画的流畅度没有任何问题,而且无论你如何用力滑动,一次只能得到一页。

标签: ios uitableview uiscrollview uigesturerecognizer


【解决方案1】:

这是一个有效的示例项目: https://github.com/rishi420/SwipeWhileScroll

您可以在此处阅读有关此主题的更多信息:

Cross Directional UIScrollViews - Can I Modify the Scrolling Behaviour?

【讨论】:

  • 感谢其他主题的链接。这对我帮助很大。我能够在那里获取部分代码(特别是gestureRecognizerShouldBegin 方法)并将其添加到我的demo 以改进它。但是,我的演示仍然不如 Instagram 的流畅,我不知道如何改进它。有任何想法吗?我很可能会接受这个赏金答案,但只是想看看是否还有其他想法。再次感谢!
【解决方案2】:

不幸的是,Apple 不支持在 UIScrollViews 中嵌入 UITableViews:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/index.html

重要

你不应该在 UIScrollView 中嵌入 UIWebView 或 UITableView 对象 对象。如果这样做,可能会导致意外行为,因为触摸 两个对象的事件可能会混淆和错误处理。

不过话虽如此,但仍有可能实现您想要的。您是否尝试将 delayContentTouches 设置为 true 以便滚动视图将其失败的滚动手势(即水平滚动)发送给其子级(即您的表格视图)?

self.yourScrollView.panGestureRecognizer.delaysTouchesBegan = true

【讨论】:

  • 感谢您的建议,但不幸的是他们没有工作:(
【解决方案3】:

虽然这个问题有一个公认的答案,但我想为可能有类似问题的其他人提供我自己的解决方案:

使用 UICollectionView 代替 UIScrollView 来分页 UITableViews

使用 UIStoryboards 的基本步骤:

  • 将 UICollectionView 添加到 Storyboard 中的 UIViewController。
  • 更新 UICollectionView 的属性以便使用分页而不是滚动,并设置布局属性以使单元格占据 UICollecionView 的完整大小。
  • 将 UITableView 添加到 UICollectionViewCell。
  • 将 UICollectionView 的 IBoulet 添加到您的 ViewController.h 并连接插座。
  • 创建一个UICollectionViewCell子类,将UITableView的IBOutlet添加到cell的.h中
  • 在您的 Storyboard 中,将 UICollectionViewCell 的 Class 类型设置为您刚刚创建的自定义单元格。
  • 为您的 UICollectionView 和 UITableView 连接 IBOutlets。
  • 最后,您需要为这两者设置委托和数据源,并实现这些方法。由于我将其作为一个快速示例进行了尝试,因此我将 ViewController 设置为 UICollectionView 和 UITableView 的委托和数据源。但是,您的实现可能与此处不同。

只要您正确配置 UICollectionView 的数据源,它的分页应该就可以了。

【讨论】:

    【解决方案4】:

    我刚刚用类似的功能做了一些事情。

    对我来说成功的是对 UIPanGestureRecognizer 进行扩展(我正在使用 swift 2;如果您愿意,我可以为 objC 重写解决方案),这样我就可以知道用户何时将手指从设备中移出.然后我想你可以向左/向右滑动。

    这是代码,我在下面解释:

    扩展 UIPanGestureRecognizer {

    public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
        state = .Ended
        NSNotificationCenter.defaultCenter().postNotification(NSNotification(name: "panningEnded", object: nil))
    }
    

    }

    这是我可以达到特定手势的 touchesEnded 的唯一方法。您所要做的就是为您发布的通知添加一个观察者,然后让用户能够滑动。让我知道这是否有用。

    亲切的问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多