gpt4 book ai didi

objective-c - Objective-C:尝试在UIScrollView中实现自己的拖动,遇到了很多问题

转载 作者:行者123 更新时间:2023-12-01 17:01:39 25 4
gpt4 key购买 nike

我试图覆盖UITableView(实际上是UIScrollView子类)中的默认行为。基本上,我的桌子占据了屏幕的三分之一,我希望能够将项目从桌子拖到屏幕的其余部分-既可以按住然后拖动,也可以垂直于桌子拖动。我能够使用默认的UIScrollView稍稍费力地实现第一种技术,但是第二种技术给我带来了一些严重的麻烦。默认的UIScrollView touchesShouldBegin / touchesShouldCancel和touchesBegan / Moved / Ended-Cancelled都可以。

我的问题是:我希望能够检测到拖动,但是我也希望在不拖动时能够滚动。为此,我必须执行拖动检测直到(包括)touchsShouldCancel被调用时的点。 (这是因为touchesShouldCancel是UIScrollView决定是继续将触摸传递到其子视图还是滚动的分支点。)不幸的是,UIScrollView的取消半径很小,并且如果用户触摸了一个单元格然后真正移动了手指很快,只有touchesBegan被调用。 (如果用户缓慢移动,通常在调用touchsShouldCancel之前会得到一些touchesMoved。)结果,我无法计算触摸方向,因为我只有touchesBegan的一个点。

如果我可以在任何给定的瞬间查询一次触摸,而不必依靠触摸回调,则可以很轻松地解决此问题,但据我所知,我无法做到这一点。如果我可以自行决定取消滚动视图(并随后调用touchesShouldCancel),或者至少延迟对touchesShouldCancel的调用,也可以解决此问题,但是我也不能这样做。

相反,我一直试图在UITableView的单独覆盖视图中捕获几个touchesBegan / Moved调用(最多2个或3个),然后将我的触摸转发到表。这样,可以确保我的表在调用touchsShouldCancel时已经知道拖动方向。您可以在此处阅读有关此方法的变体:

  • http://theexciter.com/articles/touches-and-uiscrollview-inside-a-uitableview.html
  • http://forums.macrumors.com/showthread.php?t=640508

  • (是的,它们的处理方式有所不同,但是我认为关键是在预处理完成后将触摸内容转发到UITableView。)

    不幸的是,这似乎不起作用。使用touchesBegan / Moved / Ended-Cancelled调用表视图不会移动表,也不会将它们转发到表的hitTest视图(根据我的测试,该视图是表本身还是表单元格)。更重要的是,我检查了单元格的nextResponder是什么,它原来是表,所以也不起作用。据我了解,这是因为UIScrollView在不久的某个时候切换到使用手势识别器执行重要的拖动/滚动检测,并且据我所知,您无法像手势识别器一样正常转发触摸参与其中。

    这是另一回事:尽管手势识别器已在3.2中正式发布,但它们仍在3.1.3中存在,尽管您不能使用API​​。我认为UIScrollView已经在3.1.3中使用它们。

    ew!所以这是我的问题:
  • 上面两个链接中描述的nextResponder方法似乎很新。从那以后我是在做错什么,还是UIScrollView的实现发生了根本的改变?
  • 是否可以通过UIGestureRecognizers将触摸转发到类,以确保识别器有机会处理触摸?
  • 我可以通过添加自己的UIGestureRecognizer来解决该问题,该UIGestureRecognizer可检测到我的表格视图的拖动角度,然后确保在table.gestureRecognizers之前添加的每个手势识别器都取决于我的完成。 (我认为有3个默认的UIScrollView手势识别器。有一些是 private API类,但显然都是UIGestureRecognizer子类。)我没有按名称处理任何 private 手势识别器,但我仍在操作它们,并且还使用了我对UIScrollView内部的知识,Apple并未对此进行记录。我的应用程序可以为此拒绝吗?
  • 3.1.3我要做什么? UIScrollView显然已经在使用手势识别器,但是由于API仅在3.2中可用,因此我实际上无法访问它们。

  • 谢谢!

    最佳答案

    好吧,我终于找到了解决我问题的答案。实际上有两个答案。

    复杂的解决方案:子类化UIWindow并重写sendEvent来存储最后触摸的位置。 (重写sendEvent是《事件处理指南》中提供的示例之一。)然后,滚动视图可以在调用touchesShouldCancel时查询窗口中的最后触摸。

    更简单的解决方案:不久之后,我注意到Facebook的Three20库在存储UITouch时没有保留它们。我一直认为您不应该将UITouch对象保留在本地范围之外,但是Apple的文档仅明确禁止保留。 (“UITouch对象在多点触摸序列中是持久的。处理事件时切勿保留UITouch对象。如果需要将有关触摸的信息从一个阶段转移到另一个阶段,则应从UITouch对象复制该信息。 。”)因此,将简单的UITouch存储在表中并在调用touchsShouldCancel时查询其新位置可能是合法的。

    不幸的是,在最坏的情况下,这两种技术都只能为我提供2个采样点,这并不是非常准确的方向测量。如果我可以简单地延迟表的触摸处理或手动调用touchesShouldCancel会更好,但是据我所知,这样做是很不礼貌或完全不可能/不合法的。

    关于objective-c - Objective-C:尝试在UIScrollView中实现自己的拖动,遇到了很多问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6296729/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com