重新定位/调整UIBezierPath的大小

我有一个可拖动的视图,其上有一个遮罩层。 遮罩层上有一个UIBezierPath,它使视图上的区域透明/透明(我想要的效果)。 我的最终目标是通过传递一个基于我的视图和另一个矩形(基本上我想隐藏相交的区域)的交点计算出来的CGRect来改变path的位置和大小(而不是掩模层!)。

1)我如何创build我的面具和path(在我的视图上创build一个透明的矩形):

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)我的问题是,我找不到调整path大小/重新定位的方法。 我在网上search,但找不到任何解决scheme。

这个代码不起作用,但是我能想到的是:

 //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]; } 

我怎样才能操纵我的移动functionmasklay的path? 谢谢!

您需要将更新后的path分配给move方法中的self.maskLayer.path

 // 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; 

Swift版本

这里是@ hfossli的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 

更新

我在实际操作中发现,在创buildUIBezierPath时,我只是使用了不同的初始值,而不是稍后再进行转换。 我想这将取决于目的。

这是迅速的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扩展(如果需要,用factorX,factorY修改):

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