所以,我有一个CALayer
,其中有一个面具和我想补充解决此层的面具边框。 例如,我已经设置三角面膜层,我想大约有那层边界。
任何人都可以请帮我解决这个问题呢?
所以,我有一个CALayer
,其中有一个面具和我想补充解决此层的面具边框。 例如,我已经设置三角面膜层,我想大约有那层边界。
任何人都可以请帮我解决这个问题呢?
我在swift3方法。
// Usage:
self.btnGroup.roundCorner([.topRight, .bottomRight], radius: 4.0, borderColor: UIColor.red, borderWidth: 1.0)
// Apply round corner and border. An extension method of UIView.
public func roundCorner(_ corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let path = UIBezierPath.init(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
let borderPath = UIBezierPath.init(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let borderLayer = CAShapeLayer()
borderLayer.path = borderPath.cgPath
borderLayer.lineWidth = borderWidth
borderLayer.strokeColor = borderColor.cgColor
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.frame = self.bounds
self.layer.addSublayer(borderLayer)
}
几点建议:
vImageDilate
家庭的功能(更为复杂,可能会遇到性能问题)。 CAShapeLayer
绘制边框。 考虑这个例子的代码:
- (void)drawRect:(CGRect)rect {
CAShapeLayer *maskLayer = [CAShapeLayer layer];
//Modify to your needs
CGFloat maskInsetWidth = 5.0f;
CGFloat maskInsetHeight = 5.0f;
CGFloat maskCornerRadius = 5.0f;
CGFloat borderWidth = 2.0f;
UIColor *borderColor = [UIColor blackColor];
CGRect insetRect = CGRectInset(self.bounds, maskInsetWidth, maskInsetHeight);
insetRect.size.width = MAX(insetRect.size.width, 0);
insetRect.size.height = MAX(insetRect.size.height, 0);
CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:insetRect cornerRadius:maskCornerRadius].CGPath;
if (borderWidth > 0.0f && borderColor != nil) {
CAShapeLayer *borderLayer = [CAShapeLayer layer];
[borderLayer setPath:path];
[borderLayer setLineWidth:borderWidth * 2.0f];
[borderLayer setStrokeColor:borderColor.CGColor];
[borderLayer setFillColor:[UIColor clearColor].CGColor];
borderLayer.frame = self.bounds;
[self.layer addSublayer:borderLayer];
}
[maskLayer setPath:path];
[maskLayer setFillRule:kCAFillRuleEvenOdd];
maskLayer.frame = self.bounds;
[self.layer setMask:maskLayer];
}
斯威夫特4
class CustomView: UIView {
override func draw(_ rect: CGRect) {
super.draw(rect)
self.backgroundColor = UIColor.black
//setup path for mask and border
let halfHeight = self.bounds.height * 0.5
let maskPath = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.topLeft, .bottomRight],
cornerRadii: CGSize(width: halfHeight,
height: halfHeight))
//setup MASK
self.layer.mask = nil;
let maskLayer = CAShapeLayer()
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
//setup Border for Mask
let borderLayer = CAShapeLayer()
borderLayer.path = maskPath.cgPath
borderLayer.lineWidth = 25
borderLayer.strokeColor = UIColor.red.cgColor
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.frame = self.bounds
self.layer.addSublayer(borderLayer)
}
在一般情况下,你不能轻易地设置边框的面具。 这就像要求把一个边界图像的透明像素周围。 或许它可以使用图像过滤器来完成。 在一些更具体的情况,如果你那么这里使用普通CAShapeLayer的是,这是否代码示例:
[CATransaction begin];
[CATransaction setDisableActions:YES];
CALayer *hostLayer = [CALayer layer];
hostLayer.backgroundColor = [NSColor blackColor].CGColor;
hostLayer.speed = 0.0;
hostLayer.timeOffset = 0.0;
CALayer *maskedLayer = [CALayer layer];
maskedLayer.backgroundColor = [NSColor redColor].CGColor;
maskedLayer.position = CGPointMake(200, 200);
maskedLayer.bounds = CGRectMake(0, 0, 200, 200);
CAShapeLayer *mask = [CAShapeLayer layer];
mask.fillColor = [NSColor whiteColor].CGColor;
mask.position = CGPointMake(100, 100);
mask.bounds = CGRectMake(0, 0, 200, 200);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 100, 100);
for (int i=0; i<20; i++) {
double x = arc4random_uniform(2000) / 10.0;
double y = arc4random_uniform(2000) / 10.0;
CGPathAddLineToPoint(path, NULL, x, y);
}
CGPathCloseSubpath(path);
mask.path = path;
CGPathRelease(path);
maskedLayer.mask = mask;
CAShapeLayer *maskCopy = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:mask]];
maskCopy.fillColor = NULL;
maskCopy.strokeColor = [NSColor yellowColor].CGColor;
maskCopy.lineWidth = 4;
maskCopy.position = maskedLayer.position;
// Alternately, don't set the position and add the copy as a sublayer
// maskedLayer.sublayers = @[maskCopy];
hostLayer.sublayers = @[maskedLayer,maskCopy];
_contentView.layer = hostLayer;
_contentView.wantsLayer = YES;
[CATransaction commit];
它基本上创建了一个任意路径,并将它作为面膜。 然后,它需要这层的副本描边路径。 您可能需要调整的东西,让你正在寻找确切的疗效。
如果子类CALayer
,你可以用你想要的面具实例化,并也覆盖layoutSubLayers
包括所需的边框。 这将为所有口罩工作,并应当成为新接受的答案。
可以这样做一对夫妇的方式。 下面伊利诺伊州通过做path
给定的面具,以及将其赋值给类属性将用于在构建新的边界layoutSubLayers
。 有可能的,这种方法可能会被调用多次,所以我还设置一个布尔跟踪此。 (也可以指定边界作为一个阶级属性,并删除/重新添加各一次。现在我用布尔检查。
斯威夫特3:
class CustomLayer: CALayer {
private var path: CGPath?
private var borderSet: Bool = false
init(maskLayer: CAShapeLayer) {
super.init()
self.path = maskLayer.path
self.frame = maskLayer.frame
self.bounds = maskLayer.bounds
self.mask = maskLayer
}
override func layoutSublayers() {
if(!borderSet) {
self.borderSet = true
let newBorder = CAShapeLayer()
newBorder.lineWidth = 12
newBorder.path = self.path
newBorder.strokeColor = UIColor.black.cgColor
newBorder.fillColor = nil
self.addSublayer(newBorder)
}
}
required override init(layer: Any) {
super.init(layer: layer)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}