在两个类中调用IBAction方法 [英] Call an IBAction method in two classes
问题描述
我试图在两个类中调用IBAction方法,每当我在界面构建器中创建的按钮被点击时调用。我真正想要发生的是一个NSRect出现每当按钮被点击,但按钮和我想要NSRect出现的地方在不同的视图,所以按钮是在视图A和目标的rect是在
您已经失去了 C 中的 MVC 。 Cocoa使用 Model-View- Controller 设计模式,您似乎缺少一个控制器。
创建一个控制器类(可能是 NSWindowController
的子类,以便它负责窗口)实现一个动作方法,例如 -buttonPressed: code>这是连接到你的按钮。控制器应该管理模型(在这种情况下是任何矩形表示),以便当您按下按钮时,模型被更新。
您的矩形视图应该设置为实现一个数据源模式(参见 NSTableView
datasource实现一个很好的例子),使它知道有多少和在哪里绘制矩形。如果将控制器设置为视图的数据源,则视图不需要知道模型的任何内容。
您的矩形视图应该设置为这样: / p>
RectangleView.h:
@protocol RectangleViewDataSource;
@interface RectangleView:NSView
@property(weak)id< RectangleViewDataSource>数据源;
@end
//这是提供视图的数据源协议
@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
{
//只有当我们有一个数据源时才会显示
if([dataSource conformsToProtocol:@protocol RectangleViewDataSource)])
{
//从控制器获取rect数量
NSUInteger numRects = [dataSource numberOfRectsInView:self];
for(NSUInteger i = 0; i {
NSRect currentRect = [dataSource rectangleView:self rectAtIndex:i];
//绘制矩形
NSFrameRect(currentRect);
}
}
}
@end
您可以将控制器分配为视图的数据源,并使其实现 RectangleViewDataSource
协议方法。
看起来像这样:
YourController.h :
#importRectangleView.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
{
//将此控制器分配为视图的数据源
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方法
- (NSUInteger)numberOfRectsInView:(RectangleView *)view
{
return [rects count]
}
- (NSRect)rectangleView:(RectangleView *)view rectAtIndex:(NSUInteger)anIndex
{
return [[rects objectAtIndex:anIndex] rectValue];
}
@end
Im trying to call an IBAction Method in two classes that is called whenever a button that I created in interface builder is clicked. What I really want to happen is for a NSRect to appear whenever the button is clicked but the button and the place where I want the NSRect to appear are in separate views, so the button is in View A and the destination for the rect is in View B. I have tried doing this with NSNotificationCenter but it did not work.
You are missing the C in MVC. Cocoa uses the Model-View-Controller design pattern and you seem to be missing a controller.
You should create a controller class (possibly a subclass of NSWindowController
so that it is responsible for the window) that implements an action method such as -buttonPressed:
which is connected to your button. The controller should manage the model (which in this case is whatever the rectangles represent) such that when you press the button, the model is updated. The controller should then make your rectangle view redraw itself.
Your rectangle view should be set up so that it implements a datasource pattern (see the NSTableView
datasource implementation for a good example) so that it knows how many and where to draw the rectangles. If you set your controller as the view's datasource, your view doesn't need to know anything about the model.
Your rectangle view should be set up something like this:
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
You would assign your controller as the datasource of the view and make it implement the RectangleViewDataSource
protocol methods.
The controller would look something like this:
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
这篇关于在两个类中调用IBAction方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!