我正在实现一个自定义UIControl
,看起来像一个带有 n 件的饼图:
因此我将UIControl
子类化并覆盖其drawRect:
方法。在那里,我使用CGContextAddArc
绘制 n 件。所以,我将通过一个循环取决于我必须绘制多少件,然后相应地设置startAngle
和endAngle
。
现在,对于与控件的交互,对于我来说,从触摸事件中识别哪些的部件已被触摸是很重要的。我的方法是使用CGContextPathContainsPoint
。但是我需要在drawRect:
之外调用它,因此CGContext
不可用。
func indexOfTrackForPoint(point: CGPoint) -> Int
{
// Configure parameters
let basicTrackAngle = CGFloat(360 / tracks.count)
let strokeWidth = 60.0
let radius = CGFloat((CGFloat(self.frame.size.width) - CGFloat(strokeWidth)) / 2) - CGFloat(margin)
// Initialize the context
var context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, CGFloat(strokeWidth))
CGContextSetStrokeColorWithColor(context, UIColor.blackColor().CGColor)
for i in 0...tracks.count-1 {
// Start and end angles of current track
var currentTrackStartAngle = CGFloat(i) * basicTrackAngle
var currentTrackEndAngle = currentTrackStartAngle + basicTrackAngle
CGContextAddArc(context, center.x, center.y, CGFloat(radius), toNormalizedRadian(currentTrackStartAngle), toNormalizedRadian(currentTrackEndAngle), 0)
if pointOnPath(point, inContext: context){
println("point found on track: \(i)")
return i
}
CGContextDrawPath(context, kCGPathStroke) // or kCGPathFillStroke to fill and stroke the circle
}
}
有谁知道如何实现这一目标?是否可以将CGContext置于drawRect:
之外?
答案 0 :(得分:1)
您可以在UIBezierPath
实施中存储一组drawRect
个对象。然后,您可以使用UIBezierPath
实例方法containsPoint:
答案 1 :(得分:0)
自己想出来。可以通过使用与视图的初始上下文大小相同的UIGraphicsBeginImageContext(CGSizeMake(250.0, 250.0))
创建自己的上下文来解决该问题。整个方法现在看起来像这样:
func indexOfTrackForPoint(point: CGPoint) -> Int
{
// Configure parameters
let basicTrackAngle = CGFloat(360 / tracks.count)
let strokeWidth = 60.0
let radius = CGFloat((CGFloat(self.frame.size.width) - CGFloat(strokeWidth)) / 2) - CGFloat(margin)
// Initialize the context
UIGraphicsBeginImageContext(CGSizeMake(250.0, 250.0)) // THIS LINE SOLVES MY ISSUE
var context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, CGFloat(strokeWidth))
CGContextSetStrokeColorWithColor(context, UIColor.blackColor().CGColor)
for i in 0...tracks.count-1 {
// Start and end angles of current track
var currentTrackStartAngle = CGFloat(i) * basicTrackAngle
var currentTrackEndAngle = currentTrackStartAngle + basicTrackAngle
CGContextAddArc(context, center.x, center.y, CGFloat(radius), toNormalizedRadian(currentTrackStartAngle), toNormalizedRadian(currentTrackEndAngle), 0)
if pointOnPath(point, inContext: context){
println("point found on track: \(i)")
return i
}
CGContextDrawPath(context, kCGPathStroke)
}
println("point not found on arcs")
return -1
}