2011-05-31 14 views
2

我試圖建立一些iOS應用程序,同時學習,並有一些麻煩理解正確的方法來做到這一點。如何使用drawRect更新我的自定義UIView?

我目前有一個視圖是UIView的子類。很明顯,我想用它作爲繪圖表面。它會坐在別的東西之上,如描圖紙。

用戶應該能夠點擊一個點然後另一個點和一條線應該在2點之間畫。我得到觸摸數據,我有點,我可以從drawRect內部畫東西:最初。

問題是我不知道以後如何更新內容。當一切都加載和drawRect:是calle,它會畫一條線就好了。但是,如何根據用戶正在做什麼來繪製新東西或更改已繪製的東西。我知道我需要調用setNeedsDisplay,但不知道如何獲取數據到視圖來繪製東西。

我讀過一堆教程/例子,他們都停在「覆蓋drawRect:並畫出一些東西......完成!」。如何將數據傳遞給視圖以告訴它「嘿,重繪這些東西並添加這個新行」。

或者,我是否在談論這一切錯誤的方式?

編輯: 我會盡力解釋我的設置。

我有一個VC。在VC的視圖中,我在底部有一個工具欄。該地區的其餘部分被2個景觀佔用。一個是保存參考圖像的圖像視圖。一個是自定義視圖,清晰(描圖紙),位於頂部。他們點擊工具欄上的一個按鈕,打開一個gesturerecognizer。他們點擊屏幕,我收集點擊數據,關閉gesturerecognizer和HOPEFULLY畫一條線。除了繪圖部分,我已經完成了所有工作。

+2

你說你 「之分」。你如何儲存它們? – 2011-05-31 21:51:48

+0

CGPoints包含每個「行」的開始和停止的座標位置。現在他們正在被風險投資持有。 – 2011-05-31 22:04:08

回答

4

你是在正確的軌道上。聽起來像你需要跟蹤點。

下面是一些示例代碼。

LineDrawView.h

#import <UIKit/UIKit.h> 
@interface LineDrawView : UIView 
{ 
    NSMutableArray *lines; 
    CGPoint pointA, pointB; 
    BOOL activeLine; 
} 
@end 

LineDrawView.m

#import "LineDrawView.h" 
@implementation LineDrawView 
- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     self.backgroundColor = [UIColor blackColor]; 
     lines = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 
- (void)dealloc 
{ 
    [lines release]; 
    [super dealloc]; 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesBegan:touches withEvent:event]; 
    CGPoint point = [[touches anyObject] locationInView:self]; 
    if ([lines count] == 0) pointA = point; 
    else pointB = point; 
    activeLine = YES; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesMoved:touches withEvent:event]; 
    pointB = [[touches anyObject] locationInView:self]; 
    [self setNeedsDisplay]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [super touchesEnded:touches withEvent:event]; 
    pointB = [[touches anyObject] locationInView:self]; 
    [lines addObject:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:pointA], [NSValue valueWithCGPoint:pointB], nil]]; 
    pointA = pointB; 
    pointB = CGPointZero; 
    activeLine = NO; 
    [self setNeedsDisplay]; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef c = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth(c, 2); 
    CGContextSetLineCap(c, kCGLineCapRound); 
    CGContextSetLineJoin(c, kCGLineJoinRound); 
    CGContextSetStrokeColorWithColor(c, [UIColor grayColor].CGColor); 
    for (NSArray *line in lines) 
    { 
     CGPoint points[2] = { [[line objectAtIndex:0] CGPointValue], [[line objectAtIndex:1] CGPointValue] }; 
     CGContextAddLines(c, points, 2); 
    } 
    CGContextStrokePath(c); 
    if (activeLine) 
    { 
     CGContextSetStrokeColorWithColor(c, [UIColor whiteColor].CGColor); 
     CGPoint points2[2] = { pointA, pointB }; 
     CGContextAddLines(c, points2, 2); 
     CGContextStrokePath(c); 
    } 
} 
@end 
+0

我讀了touchesBegan等。他們似乎不是我想要的。我編輯了我的問題,試圖闡述我在做什麼。我正在使用一個VC,並且VC打開/關閉了一個手勢識別器,用於處理用戶正在做什麼。我收集的要點很好,並存儲他們罰款。我只是不知道如何將這些數據傳遞給視圖來完成繪圖。 糾正我,如果我錯了,但你的解決方案似乎完全依賴於自定義UIView。我希望它在自定義UIView是愚蠢的地方工作。並且只根據我從VC傳遞給它的數據繪製線條。 我對這種做法有錯嗎? – 2011-05-31 22:24:56

+1

不,你沒有錯,你的方法應該正常工作。你應該能夠忽略'touches'方法並直接從不同的類中填充'line'數組。只要你在更新數組後立即調用'setNeedsDisplay',點和線的填充就沒有關係。 – tidwall 2011-05-31 23:11:54

+0

哦..我是個白癡。我只需要在VC中設置一些自定義視圖變量,然後調用setNeedsDisplay不是嗎? – 2011-05-31 23:36:51

相關問題