向我的UIView添加投影的最佳方法是什么

时间:2012-03-18 18:46:51

标签: ios uiview shadow cliptobounds

我正在尝试为彼此叠加的视图添加投影,视图会崩溃,允许其他视图中的内容被看到,在这种情况下,我希望保持view.clipsToBounds ON,以便视图崩溃,其内容被剪裁。

这似乎让我很难为图层添加投影,因为当我转动clipsToBounds时,阴影也会被修剪。

我一直试图操纵view.frameview.bounds以便为框架添加阴影但允许边界足够大以包含它,但是我没有运气

以下是我用来添加阴影的代码(这仅适用于clipsToBounds OFF,如图所示)

view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;

以下是应用于最轻的灰色层的阴影的屏幕截图。希望这可以让我了解如果clipsToBounds关闭,我的内容将如何重叠。

Shadow Application.

如何为我的UIView添加阴影并保留我的内容?

编辑:只是想补充说我还使用了带阴影的背景图片,这确实很有效,但是我仍然想知道最好的编码解决方案。

7 个答案:

答案 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)

诀窍是正确定义视图层的masksToBounds属性:

view.layer.masksToBounds = NO;

它应该有用。

Source

答案 3 :(得分:13)

您可以为UIView创建扩展,以便在设计编辑器中访问这些值

Shadow options in design editor

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)

您也可以从故事板中为您的视图设置阴影

enter image description here

答案 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的头文件

通常使用此属性明确指定路径      *改善渲染性能,因为将共享同一路径      *跨层引用

一个鲜为人知的技巧是在多个层之间共享相同的参考。当然,它们必须使用相同的形状,但这在表/集合视图单元格中很常见。

我不知道为什么如果您共享实例,它会变得更快,我想它会缓存阴影的渲染并可以将其重新用于视图中的其他实例。我想知道

是否更快