2014-05-01 24 views
6

我如何掩蓋CALayer的陰影,使陰影只在路徑之外?我不想在透明視圖背後留下陰影。掩蓋CALayer陰影僅限於直腸外

shadowLayer.shadowOffset = CGSizeMake(x, y); 
shadowLayer.shadowRadius = radius; 
shadowLayer.shadowOpacity = opacity; 
shadowLayer.shadowColor = color.CGColor; 
shadowLayer.shadowPath = [UIBezierPath bezierPathWithRect:view.bounds].CGPath; 

謝謝。

+1

您可能必須製作一個僅用於陰影的透明圖層,然後遮罩該圖層,然後在沒有陰影的情況下顯示圖層。 –

+0

好吧,掩蔽部分是我遇到麻煩的地方,掩蓋了內部。 – ssteinberg

+1

我不確定細節,但是您可能需要製作比陰影邊緣更大的形狀圖層,然後添加一個與要遮罩的區域大小相同的路徑,然後使用該形狀圖層作爲帶有陰影的圖層蒙版。您可能需要使用填充模式來獲取正確工作的路徑交集。 –

回答

7

我會回答我自己的問題。爲view添加新的陰影圖層。如果設置正確,這應該適用於任何shadowPath

float radius = 8; 
float opacity = 0.5f; 
float x = 4; 
float y = 6; 
UIColor *color = [UIColor blackColor]; 

// Shadow layer 
CALayer *shadowLayer = [CALayer layer]; 
shadowLayer.shadowOffset = CGSizeMake(x, y); 
shadowLayer.shadowRadius = radius; 
shadowLayer.shadowOpacity = opacity; 
shadowLayer.shadowColor = color.CGColor; 
shadowLayer.shadowPath = [UIBezierPath bezierPathWithRect:view.frame].CGPath; // Or any other path 

// Shadow mask frame 
CGRect frame = CGRectInset(view.layer.frame, -2*radius, -2*radius); 
frame = CGRectOffset(frame, x, y); 

// Translate shadowLayer shadow path to mask layer's coordinate system 
CGAffineTransform trans = CGAffineTransformMakeTranslation(-view.frame.origin.x-x+2*radius, 
                  -view.frame.origin.y-y+2*radius); 

// Mask path 
CGMutablePathRef path = CGPathCreateMutable(); 
CGPathAddRect(path, nil, (CGRect){.origin={0,0}, .size=frame.size}); 
CGPathAddPath(path, &trans, shadowLayer.shadowPath); 
CGPathCloseSubpath(path); 

// Mask layer 
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; 
maskLayer.frame = frame; 
maskLayer.fillRule = kCAFillRuleEvenOdd; 
maskLayer.path = path; 

shadowLayer.mask = maskLayer; 

[view.layer.superlayer insertSublayer:shadowLayer below:view.layer]; 
+0

相當一些代碼實現這樣一個簡單的東西,但完美的作品!謝謝 – edwardmp

1

只是一個提前:u可以使用CAShapeLayer設置陰影

let shapeLayer = CAShapeLayer() 
shapeLayer.lineWidth = 2 
shapeLayer.fillColor = UIColor.clear.cgColor 
shapeLayer.strokeColor = UIColor.purple.cgColor 
shapeLayer.shadowColor = UIColor.black.cgColor 
shapeLayer.shadowOffset = CGSize(width: 0, height: 3) 
shapeLayer.shadowOpacity = 1 
view.layer.addSublayer(shapeLayer) 
0

ssteinberg's的回答讓我在IOS 10.2和斯威夫特3.我能使用他的回答與UIVisualEffectView創造美麗模糊,但也有一個影子。這裏轉換爲Swift 3:

let shadowLayer = CALayer() 

let mutablePath = CGMutablePath() 
let maskLayer = CAShapeLayer() 

let xOffset = CGFloat(4) 
let yOffset = CGFloat(6) 
let shadowOffset = CGSize(width: xOffset, height: yOffset) 
let shadowOpacity = Float(0.5) 
let shadowRadius = CGFloat(8) 
let shadowPath = UIBezierPath(rect: frame).cgPath 
let shadowColor = UIColor.black 
let shadowFrame = frame.insetBy(dx: -2 * shadowRadius, dy: -2 * shadowRadius).offsetBy(dx: xOffset, dy: yOffset) 
let shadowRect = CGRect(origin: .zero, size: shadowFrame.size) 
let shadowTransform = CGAffineTransform(translationX: -frame.origin.x - xOffset + 2 * shadowRadius, y: -frame.origin.y - yOffset + 2 * shadowRadius) 

shadowLayer.shadowOffset = shadowOffset 
shadowLayer.shadowOpacity = shadowOpacity 
shadowLayer.shadowRadius = shadowRadius 
shadowLayer.shadowPath = shadowPath 
shadowLayer.shadowColor = shadowColor.cgColor 

mutablePath.addRect(shadowRect) 
mutablePath.addPath(shadowLayer.shadowPath!, transform: shadowTransform) 
mutablePath.closeSubpath() 

maskLayer.frame = shadowFrame 
maskLayer.fillRule = kCAFillRuleEvenOdd 
maskLayer.path = mutablePath 

shadowLayer.mask = maskLayer 

layer.superlayer?.insertSublayer(shadowLayer, above: layer)