Detecting Tap Inside a Bezier Path

Detecting tap inside a bezier path

There is a function CGPathContainsPoint() it may be useful in your case.

Also be careful if you get gesture point from superview, the coordinate may not be correct with your test. You have a method to convertPoint from or to a particular view's coordinate system:

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view

Wide bezier path for point detection

Here is possible solution:

CGPathRef pathCopy = CGContextCopyPath(context);
// 16 is the width of path where we want to have hit test
CGPathRef tapPath = CGPathCreateCopyByStrokingPath(pathCopy, NULL, 16, kCGLineCapButt, kCGLineJoinMiter, 0.6);
// this path will be used for hit test
_linePath = [UIBezierPath bezierPathWithCGPath:tapPath];
[_linePath closePath];

Now somewhere we need it:

CGPoint point = [recognizer locationInView:self];
if ([_linePath containsPoint:point])
{
// work with point
}

How to make a UIBezierPath selectable

You can create an Outlet for your Custom View and add tapgesture in that custom view like this:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var arcView: customView!

override func viewDidLoad() {
super.viewDidLoad()
var tapGesture = UITapGestureRecognizer(target: self, action: "SomeMethod")
self.arcView.addGestureRecognizer(tapGesture)
}

func SomeMethod(){

//change label text
}
}

Now when ever you tap on your arcView your SomeMethod will call.And you can change your label text in that method.

For more Info refer THIS tutorial where you can find how to detect touch on Bezier Paths.

How to stroke the boundary of a uibezierpath on the inside of the path?

I am not aware of a way to stroke the inside of a path. However, you can accomplish something similar, which might work for you. If you scale down the path and move it to the center with the correct amount, it will fit nicely within the bounds you want. The visual difference between drawing inside and scaling is none for simple shapes like rectangles, rounded rects and ellipses, but will differ for more complex shapes. Consider what will happen if you stroke the letter B with "inside strokes", versus scaling it.

Here is what it looks like before and after transforming using a very wide line. As you can see, stroking a line will center it on the path, making half of it appear on each side. So to transform it, we will need to move the path by half a line width down and right, then scale it down by the line width.

Using bezierPathWithRoundedRect
line width 20, box size 200 x 300, corner radius 50

paths

The transform then becomes like this.

viewSize is your bounding box for the path

lineWidth is the width of the line

bezierPath is your UIBezierPath

CGAffineTransform transform = CGAffineTransformMakeTranslation(lineWidth / 2.0,
lineWidth / 2.0);
transform = CGAffineTransformScale(transform,
(viewSize.width - lineWidth) / viewSize.width,
(viewSize.height - lineWidth) / viewSize.height);

CGPathRef reducedPath = CGPathCreateCopyByTransformingPath(bezierPath.CGPath, &transform);


UPDATE

If you want to keep the aspect ratio, the scaling can be modified to be equal on both axis, using the smallest factor on both.

CGFloat scale = viewSize.width < viewSize.height ? (viewSize.width - lineWidth) / viewSize.width :
(viewSize.height - lineWidth) / viewSize.height;

CGAffineTransform transform = CGAffineTransformMakeTranslation(lineWidth / 2.0, lineWidth / 2.0);
transform = CGAffineTransformScale(transform, scale, scale);

CGPathRef reducedPath = CGPathCreateCopyByTransformingPath(bezierPath.CGPath, &transform);

Add gesture recognizer to BezierPath created by PaintCode

You are trying to manipulate UIBezierPath objects generated by PaintCode directly, which isn't PaintCode's purpose.

What you are trying to achieve is possible, but not without some hacking.

For example: How to access a layer inside UIView custom class generate with Paintcode?

In my opinion, you are "misusing" PaintCode.

Instead, you would be much better adding the tapping logic inside your custom UIView. The thing you called someObjectView.swift.

For example: https://github.com/backslash-f/paint-code-ui-button

In case you really need to check if gestures occur inside the boundaries of a UIBezierPath then you need to create a public reference to it (e.g.: a var that points to it outside of the drawRectangle1 function) and finally use the code proposed by @Sparky.

The main problem with this approach is that your changes will be overwritten every time you use PaintCode's export feature. I wouldn't recommend it.



Related Topics



Leave a reply



Submit