Reposicionar / cambiar el tamaño de UIBezierPath

Tengo una vista que se puede arrastrar y que tiene una capa de máscara. La capa de máscara tiene un UIBezierPath en él que crea un área en la vista transparente / transparente (el efecto que quiero). Mi objective final es cambiar la position y el tamaño de la ruta (¡no la capa de máscara!) Pasando un CGRect que se calcula en function de la intersección de mi vista y otro rectángulo (Básicamente quiero ocultar el área que se cruza).

1) Cómo creo mi máscara y ruta (crea un rectángulo transparente en mi vista):

self.maskLayer = [CAShapeLayer layer]; self.maskLayer.frame = self.contentView.bounds; //default path rect CGRect const rect = CGRectMake(CGRectGetMidX(self.contentView.bounds) , CGRectGetMidY(self.contentView.bounds), 50,50); path = [UIBezierPath bezierPathWithRect:rect]; [path appendPath:[UIBezierPath bezierPathWithRect:self.contentView.frame]]; self.maskLayer.path = path.CGPath; self.maskLayer.fillRule = kCAFillRuleEvenOdd; self.contentView.layer.mask = self.maskLayer; 

2) Mi problema es que no pude encontrar una forma de cambiar el tamaño / reposicionar solo el path. Busqué en línea pero no pude encontrar ninguna solución.

Este código no funciona pero es lo que puedo pensar:

 //runs while the view is being dragged(using UIPanGestureRecognizer) -(void)move{ CGRect intersectedRect = CGRectIntersection(self.frame, self.productView.frame); path = [UIBezierPath bezierPathWithRect:intersectedRect]; [path appendPath:[UIBezierPath bezierPathWithRect:intersectedRect]]; [self.maskLayer setNeedsDisplay]; } 

¿Cómo puedo manipular solo la ruta de la máscara en mi function de movimiento? ¡Gracias!

self.maskLayer.path asignar la ruta actualizada a self.maskLayer.path en su método de movimiento.

 // example path UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 100, 100) cornerRadius:4]; // scale it CGFloat scale = 0.9; [path applyTransform:CGAffineTransformMakeScale(scale, scale)]; // move it CGSize translation = CGSizeMake(10, 5); [path applyTransform:CGAffineTransformMakeTranslation(translation.width, translation.height)]; // apply it self.myLayer.path = path; 

Versión Swift

Aquí está el código de @ hfossli para Swift:

 // example path let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 100, height: 100), cornerRadius: 4) // scale it let scale = CGFloat(0.9) path.applyTransform(CGAffineTransformMakeScale(scale, scale)) // move it let translation = CGSize(width: 10, height: 5) path.applyTransform(CGAffineTransformMakeTranslation(translation.width, translation.height)) // apply it self.myLayer.path = path 

Actualizar

En la práctica real, he descubierto que solo tengo diferentes valores iniciales al crear un UIBezierPath lugar de transformarlo más tarde. Supongo que dependerá del propósito.

Es rápido 3

 func move(path: UIBezierPath, fromPoint: CGPoint, toPoint: CGPoint) { let moveX = toPoint.x - fromPoint.x let moveY = toPoint.y - fromPoint.y path.apply(CGAffineTransform(translationX: moveX, y: moveY)) } func scale(path: UIBezierPath, fromSize: CGSize, toSize: CGSize) { if fromSize.width == 0 || fromSize.height == 0 { return } let scaleWidth = toSize.width / fromSize.width let scaleHeight = toSize.height / fromSize.height path.apply(CGAffineTransform(scaleX: scaleWidth, y: scaleHeight)) } 

Swift 3 extensión (modifíquelo con factor X, factorY si es necesario):

 extension UIBezierPath { func scaleAroundCenter(factor: CGFloat) { let beforeCenter = self.bounds.getCenter() // SCALE path by factor let scaleTransform = CGAffineTransform(scaleX: factor, y: factor) self.apply(scaleTransform) let afterCenter = self.bounds.getCenter() let diff = CGPoint( x: beforeCenter.x - afterCenter.x, y: beforeCenter.y - afterCenter.y) let translateTransform = CGAffineTransform(translationX: diff.x, y: diff.y) self.apply(translateTransform) } }