我正在尝试实现需要对触摸作出反应的自定义图表。我使用CAShapeLayer
在视图控制器视图中绘制图形代码如下:
var PILL_GRAPH_ENDING_X_AXIS : CGFloat!
var PILL_GRAPH_BEGINNING_X_AXIS : CGFloat!
var PILL_GRAPH_DRAW_WIDTH : CGFloat!
var PILL_GRAPH_Y_AXIS : CGFloat!
var graphLayer : CAShapeLayer!
var tapGestureRecognizer : UITapGestureRecognizer!
//MARK: View Management
override func viewDidLoad() {
super.viewDidLoad()
tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "viewTapped:")
view.addGestureRecognizer(tapGestureRecognizer)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
print("View will appear has been called")
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
print("View will layout subviews")
PILL_GRAPH_Y_AXIS = view.frame.size.height/2
PILL_GRAPH_DRAW_WIDTH = 80
PILL_GRAPH_ENDING_X_AXIS = view.frame.size.width-50
PILL_GRAPH_BEGINNING_X_AXIS = 50
drawPillGraph()
}
//MARK: Graph Drawing
func drawPillGraph() {
let bezierPath = UIBezierPath()
graphLayer = CAShapeLayer()
//Prepare the line drawing
bezierPath.moveToPoint(CGPoint(x: PILL_GRAPH_BEGINNING_X_AXIS, y: PILL_GRAPH_Y_AXIS))
let endingPoint = CGPoint(x: PILL_GRAPH_ENDING_X_AXIS, y: PILL_GRAPH_Y_AXIS)
bezierPath.addLineToPoint(endingPoint)
graphLayer.opacity = 1.0
graphLayer.backgroundColor = UIColor.lightGrayColor().CGColor
graphLayer.strokeColor = UIColor.redColor().CGColor
graphLayer.lineWidth = PILL_GRAPH_DRAW_WIDTH
graphLayer.lineCap = kCALineCapRound
graphLayer.path = bezierPath.CGPath
view.layer.addSublayer(graphLayer)
}
func viewTapped(gestureRecognizer: UITapGestureRecognizer){
print("View tapped")
let touch = gestureRecognizer.locationInView(self.view)
}
这将产生如下图:
我想要做的是能够检测点击红色图表的时间以及点击图表中的特定点击点CGPoint
。我尝试了一些尝试使用hitTest:
和CGPointContainsPoint
的不同方法,但我无法成功实现我想要做的事情。如果有人有一个如何做到这一点的例子,将不胜感激。
答案 0 :(得分:1)
这是我直接从我的项目中复制的一些代码(CGPathContainsPoint
代码除外)。在我的案例中,手势识别器是长按,但这是我实施hitTest:
func didLongPressView(lpGesture:UILongPressGestureRecognizer) {
let location = lpGesture.locationInView(self)
let point = self.convertPoint(location, fromView: nil)
let foundLayer = self.rootLayer!.hitTest(point)
if let shapeLayer = foundLayer as? CAShapeLayer {
// You've found a shape layer, see if the point is inside
// its path
if CGPathContainsPoint(shapeLayer.path, nil, point, false) {
// The tap was inside the shape layer's path.
}
}
}
rootLayer
变量是我的图层层次结构中的最外层(顶级父级)。
答案 1 :(得分:0)
在 Swift 3.0 中,事情有点清洁&不同。
func buttonTapped(sender: UITapGestureRecognizer) {
// Check location of tap in the View.
let location = tapGesture?.location(in: self.view)
// Convert location into a Point
let point = self.view.convert(location!, from: nil)
if shapeLayer!.path!.contains(point) {
startAnimation()
}
或使用 LongPress 示例Matt ...
func didLongPressView(sender: UILongPressGestureRecognizer) {
// Check location of long press in the View.
let location = lpGesture?.location(in: self.rootLayer)
// Convert location into a Point
let point = self.rootLayer.convert(location!, from: nil)
if shapeLayer!.path!.contains(point) {
startAnimation()
}
即。 tapGesture / lpGesture在此函数之外声明,并且ShapeLayer已在viewDidLoad中实例化为CAShapeLayer()(如下所示)....
self.shapeLayer = CAShapeLayer()
shapeLayer!.path = shapeBezier.cgPath
shapeLayer!.fillColor = UIColor.whiteColor().cgColor
self.view.layer.addSublayer(shapeLayer!)