2つのクラスでIBActionメソッドを呼び出す

私はインターフェイスビルダーで作成したボタンがクリックされるたびに呼び出される2つのクラスでIBActionメソッドを呼び出そうとしています。私が本当にしたいのは、ボタンがクリックされたときにNSRectが表示されるが、ボタンとNSRectを表示する場所が別々のビューにあるため、ボタンはビューAにあり、rectの宛先は私はNSNotificationCenterでこれをやろうとしましたが、動作しませんでした。

0

3 答え

You are missing the C in MVC. Cocoa uses the Model-View-Controller design pattern and you seem to be missing a controller.

あなたに接続されている -buttonPressed:のようなアクションメソッドを実装するコントローラクラス(場合によっては NSWindowController のサブクラス)を作成して、ボタン。コントローラは、ボタンを押すとモデルが更新されるように、モデル(この場合は長方形が表すもの)を管理する必要があります。コントローラーは、あなたの四角形のビューを再描画する必要があります。

矩形を描画する場所と場所を知るために、矩形のビューを設定してデータソースパターン(例: NSTableView データソースの実装を参照)を実装するように設定する必要があります。コントローラをビューのデータソースとして設定すると、ビューはモデルについて何も知る必要はありません。

あなたの四角形のビューは、次のように設定する必要があります:

RectangleView.h: @protocol RectangleViewDataSource;

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

//this is the data source protocol that feeds the view
@protocol RectangleViewDataSource 
- (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 
@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
2
追加された
コントローラがメソッド宣言のプロトコルに準拠していることをコントローラが宣言していることを確認しましたか? @interface YourController:NSWindowController
追加された 著者 Rob Keniger,
私はあなたが実際に何をしているのかを見ずに四角形の描画についてお手伝いすることはできません。おそらくあなたの実際のソースコードを使ってこれに別の質問を投稿することをお勧めします。
追加された 著者 Rob Keniger,
ありがとうございました!それは今働きます!
追加された 著者 Sage Washabaugh,
ああ、それは動作しますが、NSRectは描画されていないことを心配しないでください
追加された 著者 Sage Washabaugh,
そして、Xcodeはプロパティのデータソースがプロトコルに準拠していないと言っています。あなたはこれを修正する方法を知っていますか?
追加された 著者 Sage Washabaugh,
大丈夫ありがとう。
追加された 著者 Sage Washabaugh,
しかし、私のコントローラクラスが行っている間にプロパティDatasourceがプロトコルに従っていない理由を知っていますか?
追加された 著者 Sage Washabaugh,

それらは別々の窓にありますか?表示されていない場合は、ViewBでIBActionを宣言し、ViewAのボタンに接続します。それらが異なるウィンドウにある場合は、NSNotificationCenterの方法で動作するはずです。同じ通知名で postNotificationName: addObserver:selector:name:object を使用しましたか?

1
追加された

rectを使ってビューについて知っているコントローラが必要です。ボタンをコントローラーに接続します。ボタンを押すと、矩形を追加します。

1
追加された