Question

I have a custom subclass of UIView, LineDrawingView. I have this as a @property in my main view controller and I add it to the view. This works fine - it creates a transparent view on top of the current view and uses UIBezierPath, touchesBegan, touchesMoved etc so you can draw all over the view by dragging your finger around.

I need to make that drawing view "L" shaped, so I can have an area in the bottom left corner where various controls are located. I can think of no way to make the drawing view "L" shaped, except maybe to add two separate rectangular drawing views, but this doesn't work because touches are interrupted when you drag your finger from one rectangle into the other. The other solution I've come up with is to add another view on top of the drawing view. This view should prevent drawing and I could also locate my controls within it so they are still usable while drawing is enabled.

I tried creating a UIView and adding it as a subview of the drawing view. I gave it a tint so I could check it was present and in the right place. I expected this to prevent drawing within the area of the new UIView, but drawing continues all over the area of the LineDrawingView. I also tried inserting the new UIView at index 2, with the LineDrawingView inserted at index 1. It still didn't affect the drawing.

    self.drawView = [[LineDrawingView alloc] initWithFrame:CGRectMake(0, 50, 768, 905)];
    [self.drawView setBackgroundColor:[UIColor clearColor]];

    // not effective in preventing drawing!!
    UIView *controlView = [[UIView alloc] initWithFrame:CGRectMake(0, 530, 310, 575)];
    [controlView setUserInteractionEnabled:NO];
    [controlView setBackgroundColor:[UIColor grayColor]];
    [controlView setAlpha:0.3];

    [self.view addSubview:drawView];
    [self.drawView addSubview:controlView];

I would love to know: how can I either...

Create an "L" shaped drawing view? OR Cut out a section of the drawing view so users can interact with what is behind it? OR Impose an area on top of the drawing view where I can disable drawing and add my controls?

Was it helpful?

Solution 2

I contacted Apple about this. It turns out there is not a way to create an "L" shaped view. The solution was to, in the drawing view, test whether touches are within the forbidden area and, if so, prevent the line from being drawn. My controls have been moved to a separate UIView which is moved to the front when drawing is enabled. This means the controls remain active the whole time and drawing cannot take place within the area of the controls.

OTHER TIPS

Here is a tutorial on creating a transparent rounded rectangle UIView, which I think you could modify in a straightforward manner to make it L shaped.

The most important thing to keep in mind that you'll have to implement your own drawRect and I believe also your own hitTest or touches (e.g. event handling like touchedBegan:withEvent:) methods.

if you want to draw an L shape drawing view you can do this by concatenating two lines only .. just like i have created an arrow .. and if you want to stop drawing while you are moving (dragging ) any object .. you just need to apply a check in your touches moved method (like is moved , )..

here is the code to draw an arrow (you can use this as a reference to draw any kind of shape) : How can I draw an arrow using Core Graphics?

code to check if you have hit the path (means your touch point is in the bezier path )

if([[self tapTargetForPath:((UIBezierPath *)[testDict objectForKey:@"path"])] containsPoint:startPoint])// if starting touch is in bezierpath
        {
                    ishitInPath = YES;
                    isMoving = YES;
}


// to easily detect (or select a bezier path object)
- (UIBezierPath *)tapTargetForPath:(UIBezierPath *)path
{
    if (path == nil) {
        return nil;
    }

    CGPathRef tapTargetPath = CGPathCreateCopyByStrokingPath(path.CGPath, NULL, fmaxf(35.0f, path.lineWidth), path.lineCapStyle, path.lineJoinStyle, path.miterLimit);
    if (tapTargetPath == NULL) {
        return nil;
    }

    UIBezierPath *tapTarget = [UIBezierPath bezierPathWithCGPath:tapTargetPath];
    CGPathRelease(tapTargetPath);
    return tapTarget;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top