Gold Challenge


#1

Added a BNRCircle class

@property (nonatomic) CGPoint point1; @property (nonatomic) CGPoint point2;

In BNRDrawView.m

Added in initWithFrame

self.circlesInProgress = [[NSMutableDictionary alloc] init]; self.finishedCircles = [[NSMutableArray alloc] init];

Added in drawRect

[code] [[UIColor blackColor] setStroke];
for (BNRCircle *circle in self.finishedCircles)
{
[self strokeCircle:circle];
}

[[UIColor redColor] setStroke];
for (NSValue *key in self.circlesInProgress)
{
    [self strokeCircle:self.circlesInProgress[key]];
}[/code]

Added strokeCircle…

[code]- (void)strokeCircle:(BNRCircle *)circle
{
CGRect r = CGRectMake(MIN(circle.point1.x, circle.point2.x),
MIN(circle.point1.y, circle.point2.y),
fabs(circle.point1.x - circle.point2.x),
fabs(circle.point1.y - circle.point2.y));

UIBezierPath *bp = [UIBezierPath bezierPathWithOvalInRect:r];
bp.lineWidth = 10;

[bp stroke];

}[/code]

Touch methods ( 1 touch = line, 2 touches = circle )

[code]- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if([touches count] == 1)
{
for (UITouch *t in touches)
{
CGPoint location = [t locationInView:self];
BNRLine *line = [[BNRLine alloc] init];
line.begin = location;
line.end = location;

        NSValue *key = [NSValue valueWithNonretainedObject:t];
        self.linesInProgress[key] = line;
    }
}

if([touches count] == 2)
{
    NSArray *touchArray = [touches allObjects];
    UITouch *t1 = [touchArray objectAtIndex:0];
    UITouch *t2 = [touchArray objectAtIndex:1];

    BNRCircle *circle = [[BNRCircle alloc]init];
    circle.point1 = [t1 locationInView:self];
    circle.point2 = [t2 locationInView:self];
    
    NSValue *key = [NSValue valueWithNonretainedObject:t1];
    self.circlesInProgress[key] = circle;
}

[self setNeedsDisplay];

}

[/code]

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{    
    if([touches count] == 1)
    {
        for (UITouch *t in touches)
        {
            NSValue *key = [NSValue valueWithNonretainedObject:t];
            BNRLine *line = self.linesInProgress[key];
            line.end = [t locationInView:self];
        }
    }
    
    if([touches count] == 2)
    {
        NSArray *touchArray = [touches allObjects];
        UITouch *t1 = [touchArray objectAtIndex:0];
        UITouch *t2 = [touchArray objectAtIndex:1];
        
        NSValue *key = [NSValue valueWithNonretainedObject:t1];
        BNRCircle *circle = self.circlesInProgress[key];
        circle.point1 = [t1 locationInView:self];
        circle.point2 = [t2 locationInView:self];
    }
    
    [self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{    
    if([touches count] == 1)
    {
        for (UITouch *t in touches)
        {
            NSValue *key = [NSValue valueWithNonretainedObject:t];    
            BNRLine *line = self.linesInProgress[key];
 
            [self.finishedLines addObject:line];
            [self.linesInProgress removeObjectForKey:key];
        }
    }
    
    if([touches count] == 2)
    {
        NSArray *touchArray = [touches allObjects];
        UITouch *t1 = [touchArray objectAtIndex:0];

        NSValue *key = [NSValue valueWithNonretainedObject:t1]; 
        BNRCircle *circle = self.circlesInProgress[key];
        
        [self.finishedCircles addObject:circle];
        [self.circlesInProgress removeObjectForKey:key];
    }

    [self setNeedsDisplay];
}

[code]

  • (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
    if([touches count] == 1)
    {
    for (UITouch *t in touches)
    {
    NSValue *key = [NSValue valueWithNonretainedObject:t];
    [self.linesInProgress removeObjectForKey:key];
    }
    }

    if([touches count] == 2)
    {
    NSArray *touchArray = [touches allObjects];
    UITouch *t1 = [touchArray objectAtIndex:0];

      NSValue *key = [NSValue valueWithNonretainedObject:t1];
      [self.circlesInProgress removeObjectForKey:key];
    

    }

    [self setNeedsDisplay];
    }[/code]


#2

The program allows for multiple touches to be created simultaneously. One could create three parallel lines in one motion… Just by dragging three fingers across the screen.

This solution seems to reduce this to one point for lines, and two points will always create a circle. what happens if a user uses three fingered at once?


#3

[quote=“AntonyBurt”]The program allows for multiple touches to be created simultaneously. One could create three parallel lines in one motion… Just by dragging three fingers across the screen.

This solution seems to reduce this to one point for lines, and two points will always create a circle. what happens if a user uses three fingered at once?[/quote]

You could actually use a if else statement such that

if ([touches count] == 2){ // Deal with the circle. } else{ // Deal with the rest of lines. }


#4

Well… But what about moving only one finger for making a circle (putting two on the screen and moving only one)? And touchesBegan method is called repeatedly very often for every touch, it’s difficult for user to tap simultaneously with both fingers, there is going to be a short delay between taps. So your touchesBegan will not work for most of situations. In my humble opinion, the only way of making gesture work is using the UIPinchGestureRecognizer… I’ve tried to get the program work for hours without it, but I haven’t managed to.

Good luck! I hope, my notes are going to be useful for you. :slight_smile: