【问题标题】:Determining which NSView instance initiated a mouseDown:确定哪个 NSView 实例启动了 mouseDown:
【发布时间】:2009-06-25 17:07:50
【问题描述】:

我有一个带有 25 块 myGameTile 的游戏板,myGameTile 是 NSView 的子类。 在 mouseDown 中:我想确定我单击了哪个图块并将 ivar 设置为代表值。

例如如果我单击 tile 12,请将 clickedTile 设置为“12”或唯一代表该特定实例的某个值。

我打开了从整数值 12 一直到某种内省/反思的任何东西,尽管内置功能和优雅比 hack、运行时包装器和修改更可取。不过,我知道我可能别无选择,只能依赖这些解决方案,所以也请回答这些问题。我想知道我所有的选择。谢谢!

【问题讨论】:

  • 这是一个标题不佳的问题。我建议将其更改为“确定游戏板上的哪个子视图被点击”之类的内容。乍一看,询问“self 是哪个实例”毫无意义。

标签: objective-c cocoa reflection nsview introspection


【解决方案1】:

您可以继承 NSView 并覆盖 tag method,如文档中所述。

【讨论】:

  • 他已经说过他已经继承了NSView...也就是说,设置标签可能是一种非常简单的方法来知道点击了哪个视图。它需要以所需的顺序手动为每个视图分配一个标签,但这似乎是一个非常可行的解决方案。 +1
【解决方案2】:

你有几种可能:

如果您在 Tile 视图中处理 mouseDown,则需要将 self 映射到 tile ID。有三种简单的方法可以做到这一点:

  • 预先配置 Tile.tag 为 tile ID,然后使用 self.tag。
  • 在 Tiles 数组中搜索 Tile 以找到索引 [parent.tiles indexOfObject:self]
  • 创建字典映射磁贴或磁贴 ID [[parent.tiles objectForKey:self] intValue]

显然,使用标签是最简单的,只要您不将标签用于其他任何事情。

或者,您可以在父视图上实现 hitTest,并返回父视图,然后在父视图中处理 mouseDown。然后 mouseDown 会知道命中在哪里,从而知道它是哪个图块。

【讨论】:

    【解决方案3】:

    我认为 hitTest: 会做你想做的事。像这样的:

    - (void)mouseDown:(NSEvent *)theEvent {
        NSPoint aPoint = [theEvent locationInWindow];
        NSView* viewHit = [self hitTest:aPoint];
        if( viewHit != nil && viewHit != self ) {
            // viewHit is our tile.
        }
    }
    

    【讨论】:

    • NSView 继承自 NSResponder,因此您可能不必手动测试这一点 — -hitTest 的文档:“此方法主要由 NSWindow 对象使用,以确定哪个视图应该接收鼠标-down 事件。您很少需要调用此方法,但您可能希望覆盖它以使视图对象从其子视图中隐藏鼠标按下事件。如果在 NSView 上调用 -mouseDown: 方法,则意味着该视图被确定为应该响应事件的视图。
    猜你喜欢
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多