问题
Is there any workaround to know where a CGpath (created using an array of co-ordinates) is closed.
I was not able to find any suitable method in the header CGPath.
I wish to track the path traced by user .If its a closed loop, then i wish to extract that part from the context. Something like masking or clipping the context but it should be user tracked clipping.
Thanks!
回答1:
Just in case you've been stuck on this for the last 4 1/2 years, here is how to do it in Swift 3. I have borrowed heavily from this answer. I really just added the isClosed() function.
extension CGPath {
func isClosed() -> Bool {
var isClosed = false
forEach { element in
if element.type == .closeSubpath { isClosed = true }
}
return isClosed
}
func forEach( body: @convention(block) (CGPathElement) -> Void) {
typealias Body = @convention(block) (CGPathElement) -> Void
let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
let body = unsafeBitCast(info, to: Body.self)
body(element.pointee)
}
print(MemoryLayout.size(ofValue: body))
let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self)
self.apply(info: unsafeBody, function: unsafeBitCast(callback, to: CGPathApplierFunction.self))
}
}
And assuming path is a CGPath or CGMutablePath, here is how you use it:
path.isClosed()
回答2:
In fact, a path can consist of multiple subpaths. A new subpath is created when you move the path's current point without connecting the two points. For the path to be closed, all its subpaths must in fact be closed.
extension CGPath {
/// Note that adding a line or curve to the start point of the current
/// subpath does not close it. This can be visualized by stroking such a
/// path with a line cap of `.butt`.
public var isClosed: Bool {
var completedSubpathsWereClosed = true
var currentSubpathIsClosed = true
self.applyWithBlock({ pointer in
let element = pointer.pointee
switch element.type {
case .moveToPoint:
if !currentSubpathIsClosed {
completedSubpathsWereClosed = false
}
currentSubpathIsClosed = true
case .addLineToPoint, .addQuadCurveToPoint, .addCurveToPoint:
currentSubpathIsClosed = false
case .closeSubpath:
currentSubpathIsClosed = true
}
})
return completedSubpathsWereClosed && currentSubpathIsClosed
}
}
来源:https://stackoverflow.com/questions/13743791/core-graphics-iphone-can-we-know-whether-a-cgpath-is-closed