无法在 UIScrollView 内的 UITableView 上同时滚动 up/down 和滚动 left/right

Can't scroll up/down and scroll left/right at the same time on UITableView within a UIScrollView

第二次更新 感谢@Segev 的评论和对另一个主题的引用,我能够改进我的 demo 以使其基本上做我想做的事。然而,它仍然不如Instagram的实现那么流畅,我想知道是否有人知道我可以如何改进它以使其更流畅?另外,我注意到有时(在我的演示中),当我快速滑动 left/right 并且我想切换到滑动 up/down 时,它仍然会继续滑动 left/right 直到我停止滑动,让它先停止。

更新: 通过继承 UIScrollView 并实现,我能够在停止滚动 up/down 后让 table 视图滑动 left/right来自 UIGestureRecognizerDelegate 的 shouldRecognizeSimultaneouslyWithGestureRecognizer 和 shouldBeRequiredToFailByGestureRecognizer 方法。如果用户正在滚动 up/down table 视图,我的想法是在 shouldRecognizeSimultaneouslyWithGestureRecognizer 中 return 为真,然后在 shouldBeRequiredToFailByGestureRecognizer 中使 table 视图的 up/down 手势失败。

但我仍然无法弄清楚如何让用户在停止初始 up/down 滚动后滚动 up/down 或 left/right(并且用户的手指仍在设备上).

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

原文: 我有几个 UITableView,它们位于启用了分页的 UIScrollView 中,并且设置为让我左右翻页,以便只有一个 UITableView 在一个时间。这是一张图(摘自

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

我想要实现的是,如果用户向下滚动 table 视图,然后松开手指(向下滚动动画仍在发生),用户可以选择向左滑动和转到下一个 table 视图的权利。现在,如果用户向下滚动 table 视图,然后在向下滚动动画仍在发生的同时抬起手指,然后将手指放回左右滑动,则不允许用户左右滚动,我无法查看已经可见的 table 视图,除非我等待 table 视图滚动完全停止,然后左右滑动。

TL;DR 基本上我无法在滚动视图中同时滚动 up/down table 和滑动 left/right,但是我希望能够做到这一点。 Activity 选项卡上的 iOS Instagram 应用就是一个例子。当 table 视图仍在滚动时,您可以向下滚动然后向右滑动。

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

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

Cross Directional UIScrollViews - Can I Modify the Scrolling Behaviour?

很遗憾,Apple 不支持在 UIScrollView 中嵌入 UITableView:

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

IMPORTANT

You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.

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

self.yourScrollView.panGestureRecognizer.delaysTouchesBegan = true

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

使用 UICollectionView 代替 UIScrollView 对 UITableView 进行分页

使用 UIStoryboard 的基本步骤:

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

只要您正确配置了 UICollectionView 的数据源,它的页面应该就很好。

我刚刚做了一些具有类似功能的东西。

对我有用的是扩展 UIPanGestureRecognizer(我正在使用 swift 2;如果你愿意,我可以重写 objC 的解决方案)这样我就可以知道用户什么时候得到手指离开设备。然后你可以滑动left/right我想。

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

扩展 UIPanGestureRecognizer {

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

}

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

亲切的问候