问题
MyNSImageView is a subclass of NSImageView, here I have:
@interface MyNSImageView : NSImageView
{
}
@end
@implementation MyNSImageView
//- (void) mouseDown: (NSEvent *) theEvent
//{
// do not wish to implement mouseDown event handler from here
//}
@end
In another class called MainView, I have:
@interface MainView : NSView
{
MyNSImageView *ImageView1;
MyNSImageView *ImageView2;
}
@end
- (void)awakeFromNib
{
ImageView1 = [[[MyNSImageView alloc] initWithFrame:NSMakeRect(5, 5, 240, 240)] autorelease];
NSImage* image1 = [[[NSImage alloc] initWithContentsOfFile: @"/Volumes/MAC DAT2/pictures/MP6107.jpg"] autorelease];
[ImageView1 setImage:image1];
[self addSubview:ImageView1];
ImageView2 = [[[MyNSImageView alloc] initWithFrame:NSMakeRect(300, 5, 240, 240)] autorelease];
image1 = [[[NSImage alloc] initWithContentsOfFile: @"/Volumes/MAC DAT2/pictures/MP5784.jpg"] autorelease];
[ImageView2 setImage:image1];
[self addSubview:ImageView2];
}
- (void) mouseDown2: (NSEvent *) theEvent
{
NSLog(@"mousedown2 from MainView");
}
- (void) mouseDown1: (NSEvent *) theEvent
{
NSLog(@"mousedown1 from MainView");
}
@end
- (void) mouseDown: (NSEvent *) theEvent
{
NSLog(@"mousedown from MainView");
}
In the MainView, when I click on the ImageView1 or ImageView2, I would like to have the mouseDown1 or mouseDown2 method to handle the event accordingly not the mouseDown method.
I have read about target/action/delegate and responder stuff, but still could not see the exact syntax to do this.
回答1:
One way to handle this is with a delegate:
First you declare a delegate protocol for your NSImageView
subclass:
@class MyNSImageView;
@protocol MyNSImageViewDelegate <NSObject>
- (void)myImageView:(MyNSImageView *)view mouseDown:(NSEvent *)event;
@end
@interface MyNSImageView : NSImageView {
}
// declare the delegate member
@property (assign) id<MyNSImageViewDelegate> delegate;
@end
@implementation MyNSImageView
@synthesize delegate = _delegate;
// In your mouseDown method, notify the delegate
- (void)mouseDown:(NSEvent *)event {
if([self.delegate respondsToSelector:@selector(myImageView:mouseDown:)]) {
[self.delegate myImageView:self mouseDown:event];
}
}
@end
Then, declare your MainView
class to implement the MyNSImageViewDelegate protocol:
@interface MainView : NSView <MyNSImageViewDelegate> {
MyNSImageView *imageView1;
MyNSImageView *imageView2;
}
@end
And in your MainView
implementation:
- (void)awakeFromNib {
// create your image views then add our instance as the delegate to each
ImageView1.delegate = self;
ImageView2.delegate = self;
}
// here we implement the `MyNSImageViewDelegate` method, which will get
// called when any `MyImageNSView` instance we've added ourselves as
// delegate to gets clicked.
- (void)myImageView:(MyNSImageView *)view mouseDown:(NSEvent *)event {
if (view == imageView1) {
NSLog(@"imageView1 clicked");
} else if (view == imageView2) {
NSLog(@"imageView2 clicked");
}
}
回答2:
You should read about the responder chain. For MyCallingClass's -mouseDown: method to be called, an instance of that class has to be in the current responder chain, and no other responder further down the chain should handle that event.
来源:https://stackoverflow.com/questions/5938270/mouse-events-handlers