重新定位/调整UIBezierPath的大小

Soc*_*Soc 12 iphone mask ios uibezierpath ios7

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

1)我如何创建蒙版和路径(在我的视图上创建一个透明矩形):

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;
Run Code Online (Sandbox Code Playgroud)

2)我的问题是我找不到一种方法来调整大小/重新定位路径.我在网上搜索但找不到任何解决方案.

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

//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];
 }
Run Code Online (Sandbox Code Playgroud)

如何在移动函数中操纵遮罩层的路径?谢谢!

hfo*_*sli 17

// 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;
Run Code Online (Sandbox Code Playgroud)


Sur*_*gch 10

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
Run Code Online (Sandbox Code Playgroud)

更新

我在实际练习中发现,在创建一个UIBezierPath而不是稍后转换它时,我只是不同的初始值.我想这取决于目的.


sab*_*and 6

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)
    }
Run Code Online (Sandbox Code Playgroud)

SWIFT 5 更新

extension UIBezierPath {

    func scaleAroundCenter(factor: CGFloat) {
        let beforeCenter = CGPoint(x: self.bounds.midX, y: self.bounds.midY)

        // SCALE path by factor
        let scaleTransform = CGAffineTransform(scaleX: factor, y: factor)
        self.apply(scaleTransform)

        let afterCenter = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
        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)
    }

}
Run Code Online (Sandbox Code Playgroud)


yur*_*ish 3

您需要self.maskLayer.path在移动方法中分配更新的路径。