2012-04-18 8 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 и добавить его в viewController, чтобы увидеть эффект.

Вопрос: Как получить чертеж, чтобы согласиться с массивом?


Update + Объяснение: Я знаю о стоимости такого подхода, но он создан только для меня, чтобы получить быстрый рисунок. Он не будет использоваться в реальном приложении, поэтому, пожалуйста, не зацикливайтесь на том, насколько это дорого. Я только создал эту возможность, чтобы получить значение в NSString (@"1,3,5,1,2,6,2,5,5,...") фигуры, которую рисую. Это станет более эффективным, когда я фактически использую его без перерисовки. пожалуйста, придерживайтесь заданного вопроса. Спасибо.

ответ

1

Я не вижу нигде, где вы фактически очищаете то, что вы нарисовали ранее. Если вы явно не очистите (например, заполняя UIRectFill(), что, в качестве стороннего, является более удобным способом рисования прямоугольников, чем заполнение явного пути), Quartz собирается просто нарисовать ваш старый контент, что приведет к неожиданному поведению на попытки стирания.

Итак ... что произойдет, если вы положили в начале -drawRect::

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

(Это, конечно, чудовищно неэффективно, но за ваш комментарий, я не обращая внимания этот факт.)

(В отдельности вы, вероятно, должны обернуть свой код рисования в парах CGContextSaveGState()/CGContextRestoreGState(), чтобы не испортить графический контекст любого вызывающего кода.)

EDIT: Я всегда забываю об этом свойстве, так как обычно я хочу рисовать более сложные фоны, но вы, скорее всего, добьетесь аналогичных результатов, установив clearsContextBeforeDrawing:YES на UIView.

+0

Ваш 'setFill' отлично работает. Но 'clearsContextBeforeDrawing: YES' не работает. Это очень неэффективно, но для моей цели это прекрасно. Спасибо. – Byte

0

Этот подход кажется мне немного странным, потому что каждый раз, когда вызывается метод touchesEnded, вам нужно перерисовать (что является дорогостоящей операцией), а также нужно отслеживать квадраты. Я предлагаю вам подкласс UIView и реализовать метод drawRect: так что представление знает, как рисовать себя и внедрять метод touchesEnded в вашем контроллере вида, где вы можете проверить, если вы коснулись квадрата, а затем удалите его из представления контроллера представления, иначе создайте квадратView и добавить его как подпункт к представлению контроллера вида.

+0

Благодарим за внимание. Если вы знаете ответ на мой фактический вопрос, пожалуйста, внесите свой вклад. Пожалуйста, просмотрите мой ответ выше. – Byte