反转基于笔划的CALayer掩码(不填充)
亲爱的堆栈溢出社区,
我在iOS(Swift)中有一个关于CAShapeLayer
的mask属性的问题。
我试图实现的是一个橡皮擦 ,通过掩盖它来擦除部分图像层。 问题出现了,当我尝试颠倒它。
我发现了一些反转path的好方法,但是这些只在使用填充path时才有用。 我想要做的就是画出一条path,用倒置的方式来掩盖图像。 笔画上的线条宽度应该在30.0
左右,看起来像橡皮擦。
我尝试了不同的事情。 我目前的版本是这样的:
- 创build一个包含橡皮擦笔划path的
CAShapeLayer
- 设置图层的
fill-color
nil
- 设置
stroke-color
和line width
- 添加图层作为图像层的蒙版
这工作正常,但它只是使图像的部分可见,在中风 。 我想扭转它。 我想到了一个黑色和白色的面具,但这是行不通的,因为面具是通过alpha通道传递的。
有没有人有一个想法如何解决这个问题?
您可以通过使用透明颜色绘制到不透明的图层来实现此目的。 这可以通过使用另一个混合模式进行绘制来完成。 不幸的是CAShapeLayer
不支持这个。 因此,你必须编写你自己的形状图层类:
@interface ShapeLayer : CALayer @property(nonatomic) CGPathRef path; @property(nonatomic) CGColorRef fillColor; @property(nonatomic) CGColorRef strokeColor; @property(nonatomic) CGFloat lineWidth; @end @implementation ShapeLayer @dynamic path; @dynamic fillColor; @dynamic strokeColor; @dynamic lineWidth; - (void)drawInContext:(CGContextRef)inContext { CGContextSetGrayFillColor(inContext, 0.0, 1.0); CGContextFillRect(inContext, self.bounds); CGContextSetBlendMode(inContext, kCGBlendModeSourceIn); CGContextSetStrokeColorWithColor(inContext, self.strokeColor); CGContextSetFillColorWithColor(inContext, self.fillColor); CGContextSetLineWidth(inContext, self.lineWidth); CGContextAddPath(inContext, self.path); CGContextDrawPath(inContext, kCGPathFillStroke); } @end
使用透明path创build图层:
ShapeLayer *theLayer = [ShapeLayer layer]; theLayer.path = ...; theLayer.strokeColor = [UIColor clearColor].CGColor; theLayer.fillColor = [UIColor colorWithWhite:0.8 alpha:0.5]; theLayer.lineWith = 3.0; theLayer.opaque = NO; // Important, otherwise you will get a black rectangle
我已经使用这个代码在绿色背景前画一个透明的圆:
编辑:这里是Swift图层的相应代码:
public class ShapeLayer: CALayer { @NSManaged var path : CGPath? @NSManaged var fillColor : CGColor? @NSManaged var strokeColor : CGColor? @NSManaged var lineWidth : CGFloat override class func defaultValue(forKey inKey: String) -> Any? { return inKey == "lineWidth" ? 1.0 : super.defaultValue(forKey: inKey) } override class func needsDisplay(forKey inKey: String) -> Bool { return inKey == "path" || inKey == "fillColor" || inKey == "strokeColor" || inKey == "lineWidth" || super.needsDisplay(forKey: inKey) } override public func draw(in inContext: CGContext) { inContext.setFillColor(gray: 0.0, alpha: 1.0) inContext.fill(self.bounds) inContext.setBlendMode(.sourceIn) if let strokeColor = self.strokeColor { inContext.setStrokeColor(strokeColor) } if let fillColor = self.fillColor { inContext.setFillColor(fillColor) } inContext.setLineWidth(self.lineWidth) inContext.addPath(self.path!) inContext.drawPath(using: .fillStroke) } }
注意 :通过使用@NSManaged
标记属性,可以通过needsDisplay(forKey inKey:)
在Swift中实现needsDisplay(forKey inKey:)
或needsDisplay(forKey inKey:)
中的needsDisplayForKey:
来轻松使属性成为animation。 我已经适应了Swift代码。
但即使不需要animation,最好用@NSManaged
来标记属性,因为QuartzCore会创build图层的副本,并且也应该复制所有的属性。 Swift中的@dynamic
是Objective C中的@dynamic
的对应@dynamic
,因为它避免了创build属性实现。 相反, CALayer
通过value(forKey:)
和setValue(_:forKey:)
获取和设置属性值。
- 在Swift中通过TouchID生成哈希或string
- Swift和Cocoapods – 缺less必需的模块
- 80年代的4月1日没有在iOS 10.0中parsing
- 如何使用丹尼尔金迪/饼图图表在swift(IOS图表)中显示百分比符号
- NSURLConnection sendAsynchronousRequest无法从闭包中获取variables
- Xcode引用一个框架,而不是与库链接二进制
- Swift和Objective-C项目 – 生成-Swift.h错误 – 找不到UIViewController的接口声明
- 如何确定什么时候所有的图像已经从Swift中的一组下载?
- 在Swift 2中创buildASYNC任务