在两个类中调用IBAction方法

时间:2011-11-25 01:40:05

标签: objective-c cocoa

我试图在两个类中调用IBAction方法,只要单击我在界面构建器中创建的按钮就会调用它。我真正希望发生的是,只要单击按钮就会出现NSRect,但按钮和我希望NSRect出现的位置在不同的视图中,因此按钮位于视图A中,而rect的目标位于查看B.我已尝试使用NSNotificationCenter执行此操作,但它无效。

3 个答案:

答案 0 :(得分:2)

您错过了 MVC 中的 C 。 Cocoa使用模型 - 视图 - 控制器 设计模式,您似乎错过了一个控制器。

你应该创建一个控制器类(可能是NSWindowController的子类,以便它负责窗口),它实现了一个连接到你的按钮的动作方法,例如-buttonPressed:。控制器应该管理模型(在这种情况下是矩形表示的任何模型),这样当您按下按钮时,模型会更新。然后控制器应该重新绘制矩形视图。

您应该设置矩形视图,以便它实现数据源模式(请参阅NSTableView数据源实现以获得一个很好的示例),以便它知道绘制矩形的数量和位置。如果将控制器设置为视图的数据源,则视图不需要了解模型的任何信息。

您的矩形视图应设置如下:

<强> RectangleView.h:     @protocol RectangleViewDataSource;

@interface RectangleView : NSView
@property (weak) id <RectangleViewDataSource> dataSource;
@end

//this is the data source protocol that feeds the view
@protocol RectangleViewDataSource <NSObject>
- (NSUInteger)numberOfRectsInView:(RectangleView*)view;
- (NSRect)rectangleView:(RectangleView*)view rectAtIndex:(NSUInteger)anIndex;
@end

<强> RectangleView.m:

@implementation RectangleView
@synthesize dataSource;

- (void)drawRect:(NSRect)rect
{
    //only draw if we have a data source
    if([dataSource conformsToProtocol:@protocol(RectangleViewDataSource)])
    {
        //get the number of rects from the controller
        NSUInteger numRects = [dataSource numberOfRectsInView:self];
        for(NSUInteger i = 0; i < numRects; i++)
        {
            NSRect currentRect = [dataSource rectangleView:self rectAtIndex:i];
            //draw the rect
            NSFrameRect(currentRect);
        }
    }
}
@end

您可以将控制器指定为视图的数据源,并使其实现RectangleViewDataSource协议方法。

控制器看起来像这样:

<强> YourController.h

#import "RectangleView.h"

@interface YourController : NSWindowController <RectangleViewDataSource>
@property (strong) NSMutableArray* rects;
@property (strong) IBOutlet RectangleView *rectView;

- (IBAction)buttonPressed:(id)sender;

@end

<强> YourController.m

@implementation YourController
@synthesize rects;
@synthesize rectView;

- (id)init 
{
    self = [super init];
    if (self) 
    {
        rects = [[NSMutableArray alloc] init];
    }
    return self;
}


- (void)awakeFromNib
{
    //assign this controller as the view's data source
    self.rectView.dataSource = self;
}

- (IBAction)buttonPressed:(id)sender
{
    NSRect rect = NSMakeRect(0,0,100,100); //create rect here
    [rects addObject:[NSValue valueWithRect:rect]];
    [self.rectView setNeedsDisplay:YES];
}

//RectangleViewDataSource methods
- (NSUInteger)numberOfRectsInView:(RectangleView*)view
{
    return [rects count];
}

- (NSRect)rectangleView:(RectangleView*)view rectAtIndex:(NSUInteger)anIndex
{
    return [[rects objectAtIndex:anIndex] rectValue];
}


@end

答案 1 :(得分:1)

它们是否在单独的窗口中?如果不是,只需在ViewB中声明一个IBAction并将其连接到ViewA中的按钮即可。如果它们位于不同的窗口中,则NSNotificationCenter方式应该可行。您是否使用postNotificationName:addObserver:selector:name:object使用相同的通知名称?

答案 2 :(得分:1)

您希望控制器知道带有rects的视图。将按钮挂到控制器上。按下按钮时,添加一个矩形。