我正在尝试为彼此叠加的视图添加投影,视图会崩溃,允许其他视图中的内容被看到,在这种情况下,我希望保持view.clipsToBounds
ON,以便视图崩溃,其内容被剪裁。
这似乎让我很难为图层添加投影,因为当我转动clipsToBounds
时,阴影也会被修剪。
我一直试图操纵view.frame
和view.bounds
以便为框架添加阴影但允许边界足够大以包含它,但是我没有运气
以下是我用来添加阴影的代码(这仅适用于clipsToBounds
OFF,如图所示)
view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
以下是应用于最轻的灰色层的阴影的屏幕截图。希望这可以让我了解如果clipsToBounds
关闭,我的内容将如何重叠。
如何为我的UIView
添加阴影并保留我的内容?
编辑:只是想补充说我还使用了带阴影的背景图片,这确实很有效,但是我仍然想知道最好的编码解决方案。
答案 0 :(得分:267)
试试这个:
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
view.layer.masksToBounds = NO;
view.layer.shadowColor = [UIColor blackColor].CGColor;
view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
view.layer.shadowOpacity = 0.5f;
view.layer.shadowPath = shadowPath.CGPath;
首先:用作UIBezierPath
的{{1}}至关重要。如果您不使用它,您可能一开始可能不会注意到差异,但敏锐的眼睛会观察到在旋转设备和/或类似事件期间发生的某种延迟。这是一项重要的性能调整。
专门针对您的问题:重要的一行是shadowPath
。它禁用视图的图层子图层的剪切,它比视图的边界延伸得更远。
对于那些想知道view.layer.masksToBounds = NO
(在图层上)和视图自己的masksToBounds
属性之间有什么区别的人:实际上并没有。切换一个会影响另一个。只是一个不同的抽象层次。
Swift 2.2:
clipToBounds
斯威夫特3:
override func layoutSubviews()
{
super.layoutSubviews()
let shadowPath = UIBezierPath(rect: bounds)
layer.masksToBounds = false
layer.shadowColor = UIColor.blackColor().CGColor
layer.shadowOffset = CGSizeMake(0.0, 5.0)
layer.shadowOpacity = 0.5
layer.shadowPath = shadowPath.CGPath
}
答案 1 :(得分:62)
Wasabii在Swift 2.3中的回答:
let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.blackColor().CGColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.CGPath
在Swift 3/4中:
let shadowPath = UIBezierPath(rect: view.bounds)
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.2
view.layer.shadowPath = shadowPath.cgPath
如果你正在使用AutoLayout,请将此代码放在layoutSubviews()中。
答案 2 :(得分:13)
答案 3 :(得分:13)
您可以为UIView创建扩展,以便在设计编辑器中访问这些值
extension UIView{
@IBInspectable var shadowOffset: CGSize{
get{
return self.layer.shadowOffset
}
set{
self.layer.shadowOffset = newValue
}
}
@IBInspectable var shadowColor: UIColor{
get{
return UIColor(cgColor: self.layer.shadowColor!)
}
set{
self.layer.shadowColor = newValue.cgColor
}
}
@IBInspectable var shadowRadius: CGFloat{
get{
return self.layer.shadowRadius
}
set{
self.layer.shadowRadius = newValue
}
}
@IBInspectable var shadowOpacity: Float{
get{
return self.layer.shadowOpacity
}
set{
self.layer.shadowOpacity = newValue
}
}
}
答案 4 :(得分:6)
答案 5 :(得分:1)
在viewWillLayoutSubviews上:
override func viewWillLayoutSubviews() {
sampleView.layer.masksToBounds = false
sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor;
sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0)
sampleView.layer.shadowOpacity = 1.0
}
使用UIView扩展:
extension UIView {
func addDropShadowToView(targetView:UIView? ){
targetView!.layer.masksToBounds = false
targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
targetView!.layer.shadowOpacity = 1.0
}
}
用法:
sampleView.addDropShadowToView(sampleView)
答案 6 :(得分:0)
所以,是的,您应该选择shadowPath属性来提高性能,而且: 来自CALayer.shadowPath的头文件
通常使用此属性明确指定路径 *改善渲染性能,因为将共享同一路径 *跨层引用
一个鲜为人知的技巧是在多个层之间共享相同的参考。当然,它们必须使用相同的形状,但这在表/集合视图单元格中很常见。
我不知道为什么如果您共享实例,它会变得更快,我想它会缓存阴影的渲染并可以将其重新用于视图中的其他实例。我想知道
是否更快