Verifique UIBezierPath cerrado o no

¿Cómo comprobar que UIBezierPath es una ruta cerrada o no (la ruta cerrada es como un contorno cerrado significa que crea una forma como un triángulo, un cuadrado, un polígono, etc.) y, si está cerrado, solo completar la ruta?

Lo siguiente representa el área donde debe completar la forma; última forma de 2 que define un contorno cerrado y un contorno simple cerrado que en un solo color se puede llenar:

introduzca la descripción de la imagen aquí

Fuente de image

El siguiente es mi código para el mismo, hay 4 cuadrados en él, pero solo rellena 3 casillas; también quiero saber ¿es posible encontrar el área de área llena en pies cuadrados cuando obtengo 4 casillas aquí cómo verificar el área total que cubría en 4 casillas?

 UIBezierPath *mainPath =[UIBezierPath bezierPath]; [mainPath moveToPoint:CGPointMake(50, 100)]; [mainPath addLineToPoint:CGPointMake(0, 100)]; [mainPath addLineToPoint:CGPointMake(0, 150)]; [mainPath addLineToPoint:CGPointMake(50, 150)]; [mainPath addLineToPoint:CGPointMake(50, 200)]; [mainPath addLineToPoint:CGPointMake(100, 200)]; [mainPath addLineToPoint:CGPointMake(100, 150)]; [mainPath addLineToPoint:CGPointMake(50, 150)]; [mainPath addLineToPoint:CGPointMake(50, 100)]; [mainPath addLineToPoint:CGPointMake(100, 100)]; [mainPath addLineToPoint:CGPointMake(150, 100)]; [mainPath addLineToPoint:CGPointMake(150, 150)]; [mainPath addLineToPoint:CGPointMake(100, 150)]; [mainPath addLineToPoint:CGPointMake(100, 100)]; CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init]; shapeLayer.lineWidth = 5.0; shapeLayer.strokeColor = [UIColor blueColor].CGColor; shapeLayer.path =mainPath.CGPath; shapeLayer.fillColor = [[UIColor networkingColor] colorWithAlphaComponent:0.5].CGColor; [[self.view layer] addSublayer:shapeLayer]; 

He respondido una pregunta similar sobre CGPath aquí . Como puede get el CGPath para un UIBezierPath , creo que también se aplica aquí. Esto es para Swift 3.x. He tomado prestado mucho de esta respuesta , agregando la function isClosed() .

 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)) } } 

Así es como lo usa:

 myBezierPath.cgPath.isClosed() 

Por qué no usa mainPath.closePath automáticamente cerrará la ruta para usted y lo llenará. Si desea tener más información sobre la ruta de cierre de forma automática o manual, puede echar un vistazo aquí , dijo que:

La diferencia es que el método [closePath] en realidad agrega un elemento de ruta adicional al CGPath subyacente que respalda el UIBezierPath.

Si usa [closePath], entonces se añadirá un CGPathElement adicional con un tipo de kCGPathElementCloseSubpath al final de la ruta inmediatamente después de ese último segmento de línea.

Para el área cubierta, puede get el cuadro delimitador de su UIBezierPath pero creo que podría ser más sencillo tener UIBezierPath diferente (uno para cada uno de su cuadrado) y luego calcular el cuadro delimitador para cada cuadrado. Si desea tener el cuadro delimitador de su ruta:

 let bounds = CGPathGetBoundingBox(yourPath.CGPath)