如何获得一个UIBezierPath的反向path

self.myPath=[UIBezierPath bezierPathWithArcCenter:center radius:200 startAngle:0 endAngle:180 clockwise:YES]; 

(这一点我可以起来运行一些谷歌search帮助..)

我有这条路 现在我想填补这个path的相反,所以留下这个部分,填补一切。 任何人都可以帮我编码。 我没有太多的信息。

>问题

在这里输入图像说明

在使用Cemal之后它显示的区域以前它只显示了一个有红色中风的圈子。

>新编辑

 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor whiteColor]; self.punchedOutPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 400, 400)]; self.fillColor = [UIColor redColor]; self.alpha = 0.8; } return self; } - (void)drawRect:(CGRect)rect { [[self fillColor] set]; UIRectFill(rect); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut); [[self punchedOutPath] fill]; CGContextSetBlendMode(ctx, kCGBlendModeNormal); } 

在这里输入图像说明

使用bezierPathByReversingPath 。 从文档(仅iOS 6.0+):

用当前path的反向内容创build并返回一个新的贝塞尔path对象。

所以要扭转你的path,你只需要:

 UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:center radius:200 startAngle:0 endAngle:180 clockwise:YES]; self.myPath = [aPath bezierPathByReversingPath]; 

这是一个替代scheme,根本不需要倒转path。

你有一部分观点你基本上想要“剪辑”:

剪出来

假设你想要白色区域是75%alpha的[UIColor whiteColor] 。 以下是你如何快速做到这一点:

  • 你创build一个新的UIView子类。
  • 这个视图有两个属性:

     @property (retain) UIColor *fillColor; @property (retain) UIBezierPath *punchedOutPath; 
  • 你重写它的-drawRect:方法来做到这一点:

     - (void)drawRect:(CGRect)rect { [[self fillColor] set]; UIRectFill(rect); CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut); [[self punchedOutPath] fill]; CGContextSetBlendMode(ctx, kCGBlendModeNormal); } 

这里有一个警告:视图的fillColor 不能包含alpha分量。 所以在你的情况下,你会想这只是[UIColor whiteColor] 。 然后通过调用[myView setAlpha:0.75]自己应用alpha位。

这里发生了什么:这是使用名为“Destination Out”的混合模式。 在math上它被定义为R = D*(1 - Sa) ,但是通俗地说,它意味着“目的地图像,无论目的地图像是不透明的,但是源图像是透明的,并且在别处是透明的”。

因此,无论物体是透明的(即在贝塞尔path之外),还是在贝塞尔path不透明的地方,这些东西都将变得透明,就会使用目的地(即上下文中已经存在的东西)。 但是,目的地的东西一定是不透明的 。 如果它不是不透明的,混合不会做你想要的。 这就是为什么你必须提供一个不透明的UIColor ,然后直接用视图去做任何你想要的透明度。


我自己也是这样做的:

  • 该窗口具有[UIColor greenColor]背景
  • fillColor是白色的
  • punchedOutPath是一个椭圆形,从视图的边缘插入10个点。
  • 该视图具有0.75alpha

用上面的代码,我得到这个:

在这里输入图像说明

内部是纯绿色的,外面有半透明的覆盖层。


更新

如果您的封面是图片 ,那么您需要创build一个新的图片。 但原则是一样的:

 UIImage* ImageByPunchingPathOutOfImage(UIImage *image, UIBezierPath *path) { UIGraphicsBeginImageContextWithOptions([image size], YES, [image scale]); [image drawAtPoint:CGPointZero]; CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut); [path fill]; UIImage *final = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return final; } 

然后你将这个函数的结果,并把它放到一个UIImageView

你可以把它放到一个单一的屏幕应用程序到视图控制器:它将使一个黄色的背景视图和一个蓝色的层顶部,有一个椭圆形的区域被一个面具切出。

 - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // create a yellow background UIView *bg = [[UIView alloc] initWithFrame:self.view.bounds]; bg.backgroundColor = [UIColor yellowColor]; [self.view addSubview:bg]; // create the mask that will be applied to the layer on top of the // yellow background CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.fillRule = kCAFillRuleEvenOdd; maskLayer.frame = self.view.frame; // create the paths that define the mask UIBezierPath *maskLayerPath = [UIBezierPath bezierPath]; [maskLayerPath appendPath:[UIBezierPath bezierPathWithRect:CGRectInset(self.view.bounds, 20, 20)]]; // here you can play around with paths :) // [maskLayerPath appendPath:[UIBezierPath bezierPathWithOvalInRect:(CGRect){{80, 80}, {140, 190}}]]; [maskLayerPath appendPath:[UIBezierPath bezierPathWithOvalInRect:(CGRect){{100, 100}, {100, 150}}]]; maskLayer.path = maskLayerPath.CGPath; // create the layer on top of the yellow background CALayer *imageLayer = [CALayer layer]; imageLayer.frame = self.view.layer.bounds; imageLayer.backgroundColor = [[UIColor blueColor] CGColor]; // apply the mask to the layer imageLayer.mask = maskLayer; [self.view.layer addSublayer:imageLayer]; } 

这也可以回答这个问题: UIBezierPath Subtract Path

我有两个解决scheme给你。

  1. CALayer上绘制此path。 并将CALayer用作实际CALayer的掩膜层。

  2. 在添加弧之前,绘制一个与您的框架大小相同的矩形。

     UIBezierPath *path = [UIBezierPath bezierPathWithRect:view.frame]; [path addArcWithCenter:center radius:200 startAngle:0 endAngle:2*M_PI clockwise:YES]; 

我会使用第二个解决scheme。 🙂