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
The transform then becomes like this.
viewSize
is your bounding box for the pathlineWidth
is the width of the linebezierPath
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
Shrink Large Title When Scrolling (Not Uitableviewcontroller) iOS 11
How Long Does a Push Notification Sit in Queue Before Being Removed
Uibarbuttonitem Custom View in Uinavigationbar
Error Sending Archive to App Store Connect
Universal Link Broken in iOS 11.2
Core Bluetooth State Preservation and Restoration Not Working, Can't Relaunch App into Background
Gssendevent - Inject Touch Event iOS
Conditionally Hide Code from the Compiler
Get Cellid, Mcc, Mnc, Lac, Signal Strength, Quality and Network in iOS 8.3
Initwithstyle:Reuseidentifier: Not Called
Swift Put Multiple Iboutlets in an Array
Is Iboutletcollection Guaranteed to Be of Correct Order
Check If My iOS Application Is Updated
Get Version Number of iOS Universal Framework in Client
What Is the Swift Preprocessor Equivalent to iOS Version Check Comparison