2012-04-18 2 views
0

배경 : 사용자가 어딘가에 손을 대면 블록을 그립니다. 블록이 있으면 지우고 싶습니다. 블록을 관리해야하는 지점을 추적하기 위해 NSMutableArray을 사용하여 블록을 관리합니다. 사용자가 터치 할 때마다 터치 위치에 이미 블록이 포함되어 있는지 여부가 결정되고 그에 따라 어레이를 관리합니다.iOS : CGContextRef drawRect가 입력과 일치하지 않습니다.

문제 :이 문제에 대한 매우 이상한 의견이 있습니다. 우선 배열의 모든 것이 내가 원하는대로 작동합니다. 문제는 사용자가 블록을 지우고 싶을 때 발생합니다. 배열이 올바르게 유지되는 동안 도면은 배열의 변경 사항을 무시하는 것 같습니다. 마지막 점 이외의 것은 제거되지 않습니다. 사용자가 다른 곳을 클릭 할 때 깜박임조차 켜고 끕니다.

- (void)drawRect:(CGRect)rect 
{ 
    NSLog(@"drawrect current array %@",pointArray); 
    for (NSValue *pointValue in pointArray){ 
     CGPoint point = [pointValue CGPointValue]; 
     [self drawSquareAt:point]; 
    } 
} 

- (void) drawSquareAt:(CGPoint) point{ 
    float x = point.x * scale; 
    float y = point.y * scale; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextMoveToPoint(context, x, y); 
    CGContextAddLineToPoint(context, x+scale, y); 
    CGContextAddLineToPoint(context, x+scale, y+scale); 
    CGContextAddLineToPoint(context, x, y+scale); 
    CGContextAddLineToPoint(context, x, y); 

    CGContextSetFillColorWithColor(context, [UIColor darkGrayColor].CGColor); 
    CGContextFillPath(context); 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *aTouch = [touches anyObject]; 
    CGPoint point = [aTouch locationInView:self]; 
    point = CGPointMake((int) (point.x/scale), (int) (point.y/scale)); 
    NSLog(@"Touched at %@", [NSArray arrayWithObject: [NSValue valueWithCGPoint:point]]); 

    NSValue *pointValue = [NSValue valueWithCGPoint:point]; 
    int i = [pointArray indexOfObject:pointValue]; 
    NSLog(@"Index at %i",i); 
    if (i < [pointArray count]){ 
     [pointArray removeObjectAtIndex:i]; 
     NSLog(@"remove"); 
    }else { 
     [pointArray addObject:pointValue]; 
     NSLog(@"add"); 
    } 
    NSLog(@"Current array : %@", pointArray); 

    [self setNeedsDisplay]; 
} 

scale가 16 pointArray 뷰의 멤버 변수로서 정의된다

여기서 코드이다.

테스트하려면 : 이것을 UIView에 드롭하고 뷰 컨트롤러에 추가하여 효과를 확인할 수 있습니다.

질문 : 그림을 배열과 일치 시키려면 어떻게합니까?


업데이트 + 설명 :이 방법의 비용을 알고 있지만 나 빠른 수치를 얻을 수 있도록 만 생성됩니다. 실제 응용 프로그램에서는 사용되지 않으므로 비용이 많이 들지 않도록하십시오. 이 기능을 사용하여 그림을 그리는 NSString (@"1,3,5,1,2,6,2,5,5,...")의 값만 가져 왔습니다. 실제로 다시 그릴 필요가 없을 때 더 효율적으로 사용할 수 있습니다. 묻는 질문에 충실하십시오. 고맙습니다.

답변

1

이전에 그린 그림을 실제로 비우는 곳은 어디에도 없습니다. 명시 적 경로를 채우는 것보다 직사각형을 그리는 것이 더 편리합니다 (예 : UIRectFill()으로 채우는 등) 명시 적으로 지우지 않는 한 Quartz는 예전 내용을 덮어 씌우므로 예기치 않은 동작이 발생할 수 있습니다. 지우기 시도.

[[UIColor whiteColor] setFill]; // Or whatever your background color is 
UIRectFill([self bounds]); 

(이것은 물론 끔찍하게 비효율적이지만, 귀하의 의견에 따라, 나는 그 사실을 무시하고있다.)

: 당신이 -drawRect:의 시작 부분에 넣으면

그래서 ... 무슨 일이 별도로 말하면, 호출 코드의 그래픽 컨텍스트를 오염시키지 않으려면 도면 코드를 CGContextSaveGState()/CGContextRestoreGState() 쌍으로 묶어야합니다.)

편집 : 일반적으로 어쨌든 더 복잡한 배경을 그려야하므로이 속성은 항상 잊지 만 UIView에서 clearsContextBeforeDrawing:YES을 설정하면 비슷한 결과를 얻을 수 있습니다.

+0

'setFill'은 완벽하게 작동합니다. 그러나'clearsContextBeforeDrawing : YES'가 작동하지 않았습니다. 그것은 매우 비효율적이지만 제 목적을 위해서는 완벽합니다. 고맙습니다. – Byte

0

touchesEnded 메서드가 호출 될 때마다 (값 비싼 연산 임) 다시 그리기가 필요하고 사각형을 추적해야하기 때문에이 접근법은 나에게 조금 이상하게 보인다. UIView를 하위 클래스로 만들고 drawRect : 메서드를 구현하여 뷰 자체가 어떻게 그려지고 뷰 컨트롤러에서 touchesEnded 메서드를 구현 하는지를 알 수 있도록합니다. 뷰 컨트롤러에서 squareView를 만졌는지 확인한 다음 뷰 컨트롤러 뷰에서 제거합니다. 그렇지 않으면 create squareView 및 뷰 컨트롤러보기에 하위 뷰로 추가하십시오.

+0

나를 찾아 주셔서 감사합니다. 내 실제 질문에 대한 답을 알고 있다면 기부 해주십시오. 위의 업데이트 응답을 확인하십시오. – Byte

관련 문제