touchesBegan,如何获得所有的接触,而不仅仅是第一次或最后一次?

Posted

技术标签:

【中文标题】touchesBegan,如何获得所有的接触,而不仅仅是第一次或最后一次?【英文标题】:touchesBegan, how to get all touches, not just first or last? 【发布时间】:2016-12-01 06:08:54 【问题描述】:

在 SpriteKit 的 SKSpriteNodes 和其他可见节点中,响应这些节点中的触摸通常以如下方式完成:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

        if let touch = touches.first ...
 // do something with the touch location that's now in touch
// etc

这一切都很好,但是如果我想确保我得到这个(让我们想象一个......)SKSpriteNode 中的任何和所有触摸的触摸信息怎么办?

= touches.first 将条件限制为仅响应此 SKSpriteNode 内的第一次触摸。这个 SKSpriteNode 中的所有触摸是如何完成的,这样每个触摸都有其可用的位置,或者它拥有和携带的任何其他东西。

我知道。愚蠢的问题。我就是那个人。我根本看不出这是怎么做到的。

【问题讨论】:

我们谈到了阅读文档和理解每一行代码的实践——这就是派上用场的地方。 'touches.first' 返回第一次触摸,所以你应该问'什么是触摸?'。然后当您查看方法签名时,您会看到“touches”是一个“Set”。当您按住 alt 键单击“触摸”时,您还会在 Xcode 中看到带有工具提示的内容。现在您的问题是“如何访问集合的每个成员”,因此请前往 Swift 文档和集合参考中的“集合”信息。练习问这些问题:-) 缺少:“最好的方法?”,“最有效的?”,“最灵活的方法是什么?”和其他我不敢问的主观问题,但想回答。我知道它是Set,来自Set&lt;UITouch&gt;,我知道如何通过for loop... 访问Set 的内容,但这肯定不是最好/正确/灵活的方式来做与处理一样重要的事情触动……对吧? ! @史蒂夫艾夫斯。然后需要multipleTouchEnabled,我只能通过反复试验来学习。还有其他人也有同样的问题,后面的人。 但最让我烦恼的是,所有应该/可能/将是使用 SpriteKit 所固有的各种事物的文档(如果 Apple 关心它并且有很多用户), 充其量是节省... 【参考方案1】:

除非multipleTouchEnabled 属性设置为true,否则视图通常不会响应多次触摸。

mySprite.multipleTouchEnabled = true

您会注意到 touchesBegan:event: 方法不返回单个 UITouch 对象,而是返回 UITouch 对象的 Set(也称为无序集合)。

在此方法中,您可以(例如)迭代集合以检查每次触摸的条件,而不仅仅是从集合中获取第一次触摸。

for touch in touches 
  // do something with the touch object
  print(touch.location(mySKNodeObject))

【讨论】:

这就是答案 真的到这个程度了吗? @Fluidity 没有比这更好、更严格的了?没有什么比这更...优雅和有目的的了吗? 并非没有更多信息。例子不胜枚举。 @Confused 如果您了解集合是如何工作的,那么您就会知道如何使用一组触摸。你想用所有这些接触做什么?没有迭代就没有办法得到它们,因为它们是一个集合。 我们需要你提供更多的上下文 哦,等等,您想要特定于一个节点。我可以写第二个答案,@Confused,但这里有很多例子。在此处搜索文档或:“subclassing sknode”和“overriding sknode touchesBegan”【参考方案2】:

除了 Commscheck 的回答之外,您还可以通过以下方式检查节点是否位于某个位置:

for _touch in touches 
   let aTouch = _touch.location(in: self)
   if nodes(at: aTouch).contains(desiredNode) 
     print("desired node found")
     desireNode.doSomething()

     // You can also do, 
     // if desiredNode.contains(aTouch) 
   

使用SKScene.nodes,然后使用.contains,因为nodes 是一个数组; SKScene 继承自 SKEffectsNode,而 SKEffectsNode 继承自 SKNode.. 命令单击顶部的 SKScene,或在导航器中显示到类层次结构,您可以一直跟踪这个 nodes 到它的起源...

open func nodes(at p: CGPoint) -&gt; [SKNode]

您可以输入“SKScene”,然后输入“.”。查看所有成员的列表以及实现它们的正确方法。

另外,如果您通常只需要在一个特定节点上执行操作,您可以将 SKNode 子类化(制作您自己的自定义节点),然后覆盖其touches_ 方法。

这里有很多很好的答案展示了如何做到这一点:)

【讨论】:

这变得非常有帮助,解决了我的菜单按钮触摸状态问题,因为其他问题你都是咸的和弯曲的;) 呵呵@Confused 我看到你终于有时间支持我的答案了:P 也许现在我能负担得起像你这样的赏金。 ty

以上是关于touchesBegan,如何获得所有的接触,而不仅仅是第一次或最后一次?的主要内容,如果未能解决你的问题,请参考以下文章

如何进行接触传播?

接触延迟开始

UIScrollView touchesBegan

如何设计保留历史而不重复的数据库模式?

如何以编程方式添加 touchesBegan 动作?

你如何知道在 touchesBegan 中被触摸的对象是啥?