2

2 つの異なるサブクラスで重複している数行の描画コードがあります。この描画コードを独自のクラスに移動してから呼び出すと、呼び出されますdrawRectが、画面に描画されることはありません。drawRect2 つの異なる: メソッドでコードが重複するのを防ぐ正しい方法は何ですか?

詳細: と をサブクラス化してカスタム コントロールを作成していNSTableViewますNSTableCellView。私の描画コードはdrawRect、これらのサブクラスの両方にある必要があります。

1 つのメソッドを宣言する NSObject のサブクラスを作成しました。実装は次のとおりです。

@implementation TNLChartDrawingExtras

- (void)drawDividersInRect:(NSRect)rect startingAtDate:(NSDate *)startDate withZoomFactor:(NSNumber *)zoomFactor {

    float pos = 0;
    NSDate *currentDate = [startDate copy];

    while (pos < rect.size.width) {

        //draw the vertical divider
        NSBezierPath *linePath = [NSBezierPath bezierPathWithRect:NSMakeRect(pos, 0.0, 1.0, rect.size.height)];
        [[NSColor colorWithCalibratedWhite:0.85 alpha:0.5] set];
        [linePath fill];

        //increment the values for the next day
        currentDate = [NSDate dateWithTimeInterval:86400 sinceDate:currentDate]; // add one day to the current date
        pos = pos + (86400.0/ [zoomFactor floatValue]);
    }
}

NSTableView サブクラスで、このオブジェクトのプロパティを定義します。次に、awakeFromNibこのクラスのインスタンスを作成します。

- (void)awakeFromNib {
    self.extras = [[TNLChartDrawingExtras alloc] init];
}

私はこのdrawRect:メッセージを送ります:

- (void)drawRect:(NSRect)dirtyRect {
    // more code here...

    [self.extras drawDividersInRect:viewBounds startingAtDate:chart.startDate withZoomFactor:self.zoomFactor];
}

コードは実行されますが、描画されるはずの線が表示されません。drawDividersInRect:...からのコードをdrawRect:メソッドに入れると、正常に動作します。

4

2 に答える 2

1

デバッグを続けていれば、元のソリューション(質問で説明)が機能した可能性があります。しかし、もっと重要な問題は、この問題に取り組む正しい方法は何かということだと思います。ここでは、NSViewのカテゴリをプロジェクトに追加して解決します。

NSTableViewとの両方にカスタム描画コードを追加しようとしていNSTableCellViewます。どちらものサブクラスなNSViewので、のカテゴリを作成し、NSViewそこにカスタム描画メソッドを追加しました。これで、両方のサブクラスから描画メソッドを呼び出すことができます。

于 2012-12-19T08:40:36.527 に答える
0

コードがまったく表示されない場合、プロトコルが必要なように思えます。これは、Java 言語のインターフェースと同じものです。プロトコルは、いくつかの無関係なクラスのグループが使用する必要がある一連のメソッドです。たとえば、PhotoShop などの描画プログラムでは、Rects、Ovals、および Images はすべて .psd ドキュメントにレイヤーとして格納できる有効なオブジェクトですが、特定の方法でオブジェクト プロパティを変更する機能などの特徴をすべて共有しています。例としては、オブジェクトの不透明度の調整やオブジェクト サイズの再スケーリングなどがあります。スケーリングのためにオブジェクト プロパティにアクセスするメソッドや、関連のないオブジェクト タイプ間で共有できる関数は、プロトコルを呼び出します。

これらは基本的に、メソッドをリストした .h ファイルです。コードの実装を定義する .m ファイルは、その .h ファイルにタグを格納できます。

// example of a class that acts as a protocol implementor
@interface LayerObject: NSObject <Resizable>

このタグは、「私は X という名前のプロトコルのメンバーです。私の .m ファイルで、プロトコル X のメソッドの 1 つまたはいくつかを見つけることができます」と述べています。次の構文を使用して、目的のクラスにプロトコルをインポートするだけです。

// Declare protocol
@protocol Resizable;
// List methods wanted from protocol
- id resizeRect: id layerObject;

プロトコルで定義されたメソッドを取得します。

これは、例を通してプロトコルを説明する Web サイトです: http://agilewarrior.wordpress.com/2012/03/19/simple-objective-c-protocol-example/

もう 1 つの解決策は、抽象クラスを使用して作業中の特定の drawRect メソッドを配置するクラス階層を作成することです。ここから、作業中の 2 つのサブクラスを、それらが継承する抽象クラスのサブクラスとして定義できます。 drawRect メソッドのコードを削除して、2 つの別々のクラスでコードを繰り返さないようにします。

于 2012-12-19T05:45:39.623 に答える