如何获得一个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.75
的alpha
用上面的代码,我得到这个:
内部是纯绿色的,外面有半透明的覆盖层。
更新
如果您的封面是图片 ,那么您需要创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给你。
-
在
CALayer
上绘制此path。 并将CALayer
用作实际CALayer
的掩膜层。 -
在添加弧之前,绘制一个与您的框架大小相同的矩形。
UIBezierPath *path = [UIBezierPath bezierPathWithRect:view.frame]; [path addArcWithCenter:center radius:200 startAngle:0 endAngle:2*M_PI clockwise:YES];
我会使用第二个解决scheme。 🙂