views:

98

answers:

3

I have a gameboard with 25 tiles of NSView subclass myGameTile. In mouseDown: I want to figure out what tile I clicked on and set an ivar to that value. i.e. If I clicked on tile 12, set myTile to 12. My problem is figuring out in mouseDown: whether it belongs to instance 12 or instance 25. What ways are there to do this?

+5  A: 

You could subclass NSView and override the tag method, as written in the documentation.

zoul
He already said that he has subclassed NSView... That said, setting the tag is probably a very simple way to know which view was clicked. It would require manually assigning a tag to each view in the desired order, but this seems like a very workable solution. +1
Quinn Taylor
A: 

I think hitTest: will do what you want. Something like this:

- (void)mouseDown:(NSEvent *)theEvent {
    NSPoint aPoint = [theEvent locationInWindow];
    NSView* viewHit = [self hitTest:aPoint];
    if( viewHit != nil && viewHit != self ) {
        // viewHit is our tile.
    }
}
blindauer
NSView inherits from NSResponder, so you probably shouldn't have to manually test this — the documentation for -hitTest: says "This method is used primarily by an NSWindow object to determine which view should receive a mouse-down event. You’d rarely need to invoke this method, but you might want to override it to have a view object hide mouse-down events from its subviews." If the -mouseDown: method is called on an NSView, it means that view was determined to be the one that should respond to the event.
Quinn Taylor
+1  A: 

You have several possibilities:

If you handle the mouseDown in the Tile view, then you need to map self to the tile ID. There are three easy ways to do this:

  • Pre configure Tile.tag to be the tile ID, then use self.tag.
  • Search for Tile in the array of Tiles to find the index [parent.tiles indexOfObject:self]
  • Create a dictionary mapping Tile or tile ID [[parent.tiles objectForKey:self] intValue]

Clearly, using the tag is the easiest, as long as you are not using the tag for anything else.

Alternatively, you could implement hitTest on the parent view, and return the parent view, and then handle the mouseDown in the parent view. Then mouseDown will know where the hit is and hence which tile it is.

Peter N Lewis