2012-12-19 50 views
2

我有幾行在兩個不同的子類中複製的繪圖代碼。當我將這個繪圖代碼移動到它自己的類中,然後從drawRect中調用它時:它被調用,但它永遠不會繪製到屏幕上。什麼是正確的方法防止在兩個不同的drawRect:方法中重複代碼?如何防止2 drawRect:方法內的重複代碼?

詳情:我正在通過繼承NSTableViewNSTableCellView進行自定義控制。我的繪圖代碼需要在drawRect:這兩個子類中。

我創建了一個聲明一個方法的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:方法中,它可以正常工作。

+1

您應該添加一些代碼,以便我們可以看到您正在嘗試的內容。 – Matt

+0

你檢查過'self.extras'不是'nil'嗎?這將解釋它。 – djromero

回答

1

如果我繼續調試它,我原來的解決方案(在問題中描述)可能已經工作。不過,我認爲更重要的問題是解決這個問題的正確方法是什麼。在這裏,我通過在項目中添加NSView類別來解決此問題:

我試圖將自定義繪圖代碼添加到NSTableViewNSTableCellView。兩者都是NSView的子類,所以我創建了一個NSView類別,並在那裏添加了我的自定義繪圖方法。現在我可以從兩個子類中調用我的繪圖方法。

+0

我同意你的解決方案。這利用了OOP範例和類繼承。如果您以後需要添加其他類型的視圖,您仍然可以訪問該方法。維護和調試也更容易。 – Matt

+0

@MikeT邁克,你能幫我解決我的問題:http://stackoverflow.com/questions/39855349/how-to-make-2-contradictory-methods-work-in-drawrect – andy

0

沒有看到任何你的代碼,這聽起來像你需要一個協議,這是一個與java語言中的接口相同的東西。協議是一系列可能需要使用一組不相關的類的一系列方法。例如,在像PhotoShop這樣的繪圖程序中,Rects,Oval和Images都是可以作爲圖層存儲在.psd文檔中的有效對象,但是,它們都共享特性,例如以特定方式更改對象屬性的能力。一個例子是調整對象的不透明度或重新縮放對象大小等。訪問用於縮放的對象屬性或可以在不相關的對象類型之間共享的函數的方法需要協議。

它們本質上是.h文件,列出了方法。定義代碼實現的.m文件可以在它的.h文件中存儲標籤。

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

標籤說,「我是名爲X的協議中的一員,你可以找到一個/一些協議X在我的.m文件的方法。」您只需使用以下語法將協議導入所需的類:

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

獲取協議中定義的方法。

這裏是一個網站,通過一個例子描述了協議: http://agilewarrior.wordpress.com/2012/03/19/simple-objective-c-protocol-example/

另一種解決方案是創建一個使用抽象類來把你在工作中給予的drawRect方法的類層次結構在這裏,您可以。定義你正在使用的兩個子類作爲它們將繼承drawRect方法代碼的抽象類的子類,從而避免在兩個單獨的類中重複代碼。

+0

不知道協議如何幫助我。我的協議基本上是一個承諾,一個班級將實施一種方法。我仍然需要在兩個不同的類中實現該方法。 –

+0

@Mike T - 無法看到您的代碼很難回答問題。我在回答底部提到了定義在層次結構中聘用的方法(即NSView)的替代解決方案。也許你應該在投票前閱讀答案。 – Matt

+0

嗨馬特 - 這不是我低估了你的答案。其實這是你的第二個解決方案,讓我思考NSView,這是由我的子類繼承的兩個類。 –