How to draw and interact with UIBezierPath

2019-07-31 15:30发布

问题:

I would like to implement and design a map for a building floor in my application. Before starting, I would like to have some advices.

I'm planning to use UIBezierPath to draw the shapes. Each UIBezierPath will represent a shop on my map. Here is an illustration (map_with_UIBezierPath)

My code structure is the following: I have a UIViewController And a UiView. In the UIViewController "viewDidLoad" method, I instantiate the UIView and in the UIView "drawRect" method, I draw the shapes like following (UIBezierPathExtension inherit from UIBezierPath):

- (void)drawRect:(CGRect)rect {

context = UIGraphicsGetCurrentContext();

[[UIColor grayColor] setFill]; 
    [[UIColor greenColor] setStroke];

UIBezierPathExtension *aPath = [[UIBezierPathExtension alloc] init]; 
aPath.pathId = 1;
    [aPath moveToPoint:CGPointMake(227,34.25)];
[aPath addLineToPoint:CGPointMake(298.25,34.75)];
[aPath addLineToPoint:CGPointMake(298.5,82.5)];
[aPath addLineToPoint:CGPointMake(251,83)];
[aPath addLineToPoint:CGPointMake(251,67.5)];
[aPath addLineToPoint:CGPointMake(227.25,66.75)];   
    [aPath closePath]; 
aPath.lineWidth = 2;
[aPath fill]; 
[aPath stroke];
[paths addObject:aPath];

UIBezierPathExtension* aPath2 = [[UIBezierPathExtension alloc] init];
aPath2.pathId = 2;
[aPath2 moveToPoint:CGPointMake(251.25,90.5)];
[aPath2 addLineToPoint:CGPointMake(250.75,83.25)];
[aPath2 addLineToPoint:CGPointMake(298.5,83)];
[aPath2 addLineToPoint:CGPointMake(298.5,90.25)];
[aPath2 closePath];
aPath2.lineWidth = 2;
[aPath2 fill]; 
[aPath2 stroke];
[paths addObject:aPath2];   

    ...
}

I have also implemented the pan and pinch gesture in the UIViewController.

Now, I'm asking me how I can interact with every single shapes. I would like to detect a single tap on it, change his color and display a menu like that on the selected shape.

Can someone tell me the right direction to take?

Thx in advance

回答1:

You need to look for touch events (TouchesBegan, TouchesMoved, TouchesEnded, TouchesCancelled) in your view. When you get a touch, you can ask it for its location in your view. You can use this location to test whether that point is inside any of your paths, if it is, do your cool stuff.

Using your example code, here might be a rough TouchesBegan...

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        CGPoint pointTouched = [touch locationInView:self];
        for (UIBezierPath *path in paths) {
            if ([path containsPoint:point]) {
                // do something cool with your path
                // or more likely, set a flag to do the cool thing when drawing
            }
        }
    }
}

Don't forget that you should handle all the touch events and do something sensible with each. Also, the above code is multitouch capable, but you may want to only allow a single touch, in which case there are ways to eliminiate the "touches" loop.