首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理多个视图的UIPanGestureRecognizer手势(一个覆盖另一个视图)

处理多个视图的UIPanGestureRecognizer手势(一个覆盖另一个视图)
EN

Stack Overflow用户
提问于 2015-07-10 19:21:44
回答 1查看 1.4K关注 0票数 1

很抱歉提出了这么长的问题,但我觉得我应该表达一下我已经尝试过的内容。

我在导航控制器中有一个视图viewA。然后,我向viewB添加了一个子视图UITableView(包含一个UITableView),并抵消了它的起始高度,这样它只覆盖了屏幕的一半(另一半从屏幕底部溢出)。我希望能够将这个viewB向上拖动,但是当它到达导航栏的底部时会停止,当它到达原点偏移点时也会同样地停止。我已经成功地做到了这一点。

但是,我希望只有当UITableView处于其较高位置时才启用viewB交互,从而不响应任何其他位置的手势。从本质上讲,将viewB拖起以使其完全覆盖viewA应该能够与UITableView进行交互。

这里的棘手之处在于,我希望它能完成以下工作:

  1. 如果viewB位于其上方,因此它正在覆盖屏幕,则UITableView内容偏移量为0(即我们位于表的顶部),并且用户向下移动一个pan手势,该手势不应与UITableView交互,而应向下移动viewB
  2. 在上述情况下,任何其他pan手势都应该是与UITableView的交互。
  3. 如果viewB位于其上位置,因此它正在覆盖屏幕,则UITableView内容偏移量在0处为而不是(也就是说,我们是在表顶部的而不是),并且用户向下做一个pan手势,该手势应该与UITableView交互。

我已经很接近实现这一目标了,但我做得不太对。

到目前为止,尝试了

我使用一个UIPanGestureRecognizer来处理视图的拖动。我试着在以下几个方面加上:

  • viewBUITableView用户交互最初禁用。这允许我在不干扰UITableView的情况下上下拖动UITableView。一旦viewB处于较高的位置,我就启用了UITableView用户交互,然后正确地允许我在不移动viewB的情况下与UITableView交互。 但是,通过启用UITableView用户交互,这意味着触摸永远不会到达UIPanGestureRecognizer,这意味着我永远无法检测到第(1)点所描述的场景。以上不能重新禁用UITableView用户交互,使viewB再次可移动. 也许可以通过重写UITableView使用的手势识别方法来做到这一点?如果可能的话,谁能给我指明正确的方向?
  • UITableView前面添加了一个新视图。我想,在必要的时候,我也许可以将触摸手势转发给UITableView,但我仍然没有找到这样的方法。 我所能做的就是禁用手势识别器,它允许我与UITableView交互,但是我也有相同的问题。我不知道什么时候该重新启用它。
  • UITableViewviewB中。这似乎是迄今为止最有希望的方式。通过设置下列方法的返回值,我可以启用和禁用对viewBUITableView的识别。 func gestureRecognizer (gestureRecognizer : UIGestureRecognizer,shouldReceiveTouch touch: UITouch) -> Bool { if PulloverVC.view.Fra.initi.y == bottomNavbarY && pulloverVC.tableView?.contentOffset.y == 0{/需要在此条件下添加手势方向检查,viewBisAtTop =真返回假//禁用套衫控制}返回真//启用套衫控制} func gestureRecognizer(gestureRecognizer: UIGestureRecognizer,gestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { if (otherGestureRecognizer as!!UIPanGestureRecognizer).velocityInView(view).y <0 && viewBisAtTop { //手势方向检查这里不需要返回真//启用表视图控件} viewBisAtTop = false返回false //禁用tableview控件} 首先调用top方法,然后是底部方法,然后是手势(我已经检查了print语句)。通过对这两个方法进行真/假的不同组合,我可以在viewBUITableView之间交替交互。 为了检测用户是否向下滑动,我在识别器上调用velocityInView() (如下面的方法所示)。我打算在top方法if语句中进行这种检查,但是我认为这是可行的,尽管velocityInView()在底部方法中工作得很好,但在顶部方法中却不是这样(速度总是为0)。

我已经搜索了一些解决方案,并发现了许多类似的关于手势处理的查询,以寻找相互覆盖的视图,但这些问题似乎都涉及一种手势类型,例如,一个视图上的夹点,另一个视图上的另一种类型,例如pan。在我的例子中,手势类型对两者是相同的。

也许有人有个聪明的主意?或者这其实很简单,我已经把这个变得非常复杂了?xD

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-11 13:36:56

设法让这件事奏效了。

在上面的问题中描述的方法中,我删除了最前面的一个,只保留了这个(它有一些更改):

代码语言:javascript
复制
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    if ((gestureRecognizer as! UIPanGestureRecognizer).velocityInView(view).y < 0
        || pulloverVC.tableView.contentOffset.y > 0)
        && pulloverVC.view.frame.origin.y == bottomNavbarY {
            return true // enable tableview control
    }
    return false
}

if语句检查覆盖UITableView位于其上级位置,以确保用户没有向下拖放,表内容被偏移(我们不在表的顶部)。如果这是真的,那么我们使用return true来启用表视图。

调用此方法后,将调用用于处理我的pan手势的标准方法。在这里,我有一个if语句,它与上面的检查正好相反,如果是这样的话,它会阻止对覆盖viewB的控制移动:

代码语言:javascript
复制
func handlePanGesture(recognizer: UIPanGestureRecognizer) {

    let gestureIsDraggingFromTopToBottom = (recognizer.velocityInView(view).y > 0)

    if pulloverVC.view.frame.origin.y != bottomNavbarY || (pulloverVC.view.frame.origin.y == bottomNavbarY && gestureIsDraggingFromTopToBottom && pulloverVC.tableView.contentOffset.y == 0) {

    ...

这将保持UITableView交互,除非它的父视图viewB位于正确的位置,并且当它处于正确位置时,禁用viewB的移动,这样只有与UITableView的交互才能工作。

然后,当我们位于表的顶部并向下拖动时,将重新禁用与UITableView的交互,并重新启用与其父视图viewB的交互。

一个冗长的帖子和答案,但如果有人能理解我的意思,希望它能帮助你。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31348739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档