【问题标题】:Why doesn't my NSView delegate method gets called?为什么我的 NSView 委托方法没有被调用?
【发布时间】:2011-12-20 02:07:34
【问题描述】:

我正在开发我的第一个 Mac 应用程序,但在获取我的 NSView 和它的委托方法时遇到了一些问题。我有一个 NSViewController 应该响应鼠标事件,即 mouseDown。这不起作用,相反,我创建了一个自定义的 NSView 子类,如下所示:

// Delegate method
@protocol CanvasViewDelegate
    - (void)mouseDown:(NSEvent *)event;
@end

@interface CanvasView : NSView
{
    id delegate;
}

@property (nonatomic, strong) id delegate;
@end

@implementation CanvasView
@synthesize delegate;

- (void)mouseDown:(NSEvent *)event
{
    [delegate mouseDown:event];
}

应该充当 NSView 的委托的 NSViewController 相关部分如下所示:

#import "CanvasView.h"

@interface PaintViewController : NSViewController <CanvasViewDelegate>
{
    CanvasView *canvasView;
}

@property (strong) IBOutlet CanvasView *canvasView;

@end 

@synthesize canvasView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
        // Initialization code here.
        canvasView = [[CanvasView alloc] init];
        canvasView.delegate = self;
    }

    return self;
}

- (void)mouseDown:(NSEvent *)event
{
    NSLog(@"Down");
}

现在,mouseDown 方法没有被调用,我做错了什么?

【问题讨论】:

  • 您刚刚分配并初始化了您的视图,但是您如何真正让您的视图出现?你不想要一个 IBOutlet 到 CanvasView,然后通过 Interface Builder 连接它吗?或者,如果您想以编程方式创建它,您是否必须使用 initWithFrame: 而不是只使用 init,然后将视图实际放在某个地方?
  • @Enchilada 我已经使用 IB 创建了视图作为 NSViewController.xib 的一部分,并将 CanvasView 分配为它的类。我将 viewConrollers 视图添加到我的应用程序委托中的窗口,如下所示:// Insert code here to initialize your application viewController = [[PaintViewController alloc] initWithNibName:@"PaintViewController" bundle:nil]; [[_window contentView] addSubview:viewController.view]; 我应该在这里设置委托吗?在那种情况下,怎么办? :)
  • 您的帖子代码中没有遗漏 [self setView:canvasView] 吗?否则,视图控制器怎么知道它的视图是什么?好吧,或者您可以在刚刚粘贴在上述注释中的代码中添加Subview:viewController.canvasView。
  • 嗯,不要认为这有帮助。委托方法仍然没有被调用。我将尝试以编程方式创建视图,看看是否有帮助。
  • 如果您还没有,请尝试添加一个 drawRect 方法,用例如红色填充视图。然后,您至少可以首先看到您的视图是否正在显示。

标签: macos cocoa delegates nsview


【解决方案1】:

如果您希望NSView 子类接受事件,则必须实现:

 - (BOOL)acceptsFirstResponder {
     return YES;
 }

如文档所述here

【讨论】:

  • 嗨,这些事件似乎只在 NSView 中起作用。例如,- (void)mouseDragged:(NSEvent *)event { NSLog(@"Dragging"); } 在 NSView 内部被调用,但如果我按照我描述的方式将其设为委托方法,则不会。
  • 那么您想让NSViewController 处理这些事件吗?您需要在将事件传递给控制器​​时调用setNextResponder:。您的委托模式并不是在这里做的真正正确的事情。查看 Cocoa 事件处理指南,尤其是响应者链部分:developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
【解决方案2】:

以编程方式创建视图确实有效。像这样:

NSRect canvasRect = self.view.frame;
canvasView = [[CanvasView alloc] initWithFrame:canvasRect];
[self.view addSubview:canvasView];
canvasView.delegate = self;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 2013-12-03
    • 2020-11-28
    相关资源
    最近更新 更多