使用Swift 3在UIView上添加阴影

83

在 Swift 3 之前,我是这样给我的 UIView 添加阴影的:

//toolbar is an UIToolbar (UIView)
toolbar.layer.masksToBounds = false
toolbar.layer.shadowOffset = CGSize(width: -1, height: 1)
toolbar.layer.shadowRadius = 1
toolbar.layer.shadowOpacity = 0.5

但是上面的代码在Swift 3中不起作用,代替阴影,整个视图的颜色变成了丑陋的灰色。

有人知道我们如何在Swift 3中添加阴影吗?

20个回答

228

代码片段:

extension UIView {

  // OUTPUT 1
  func dropShadow(scale: Bool = true) {
    layer.masksToBounds = false
    layer.shadowColor = UIColor.black.cgColor
    layer.shadowOpacity = 0.5
    layer.shadowOffset = CGSize(width: -1, height: 1)
    layer.shadowRadius = 1

    layer.shadowPath = UIBezierPath(rect: bounds).cgPath
    layer.shouldRasterize = true
    layer.rasterizationScale = scale ? UIScreen.main.scale : 1
  }

  // OUTPUT 2
  func dropShadow(color: UIColor, opacity: Float = 0.5, offSet: CGSize, radius: CGFloat = 1, scale: Bool = true) {
    layer.masksToBounds = false
    layer.shadowColor = color.cgColor
    layer.shadowOpacity = opacity
    layer.shadowOffset = offSet
    layer.shadowRadius = radius

    layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
    layer.shouldRasterize = true
    layer.rasterizationScale = scale ? UIScreen.main.scale : 1
  }
}

注意:如果您没有向该函数传递任何参数,则比例参数将默认为true。您可以通过在该参数类型之后对参数分配一个值来定义函数中任何参数的默认值。如果定义了默认值,则在调用函数时可以省略该参数。

输出1:

shadowView.dropShadow()

输入图片描述

shadowView.dropShadow(color: .red, opacity: 1, offSet: CGSize(width: -1, height: 1), radius: 3, scale: true)

在此输入图片描述

layer.shouldRasterize = true会使阴影静态化,并为UIView的初始状态产生阴影。因此,我建议不要在动态布局中使用layer.shouldRasterize = true,例如在UITableViewCell中放置的视图。


1
如果我想要去除这个阴影,我该怎么做? - Suhas Arvind Patil
8
如果你想要去除阴影,那么为什么一开始还要添加它呢?能否详细说明你的情况,这样我才能给你一个解决方案。 - aashish tamsya
1
为什么我们在这里进行光栅化?在我看到使用阴影的视图中,对图像进行了像素化处理。 - davidrynn
1
这里有些东西会使阴影获得固定大小,因此对于不同的设备来说并不好。 - Daniel Beltrami
1
在Swift 4.2中对我有效,如果你想添加阴影,请这样做: viewLoginCustom.dropShadow(color: yourColor, opacity: 1, offSet: CGSize.zero, radius: 3, scale: true) - Ravi
显示剩余8条评论

59

使用UIView扩展在Swift 4中实现阴影

我想在选定的答案中再添加一行!当我们对图层进行光栅化时,它需要设置为2.0以适应Retina显示屏。否则,该视图上的标签文本或图像会变得模糊。因此,我们还需要添加rasterizationScale

  extension UIView {

    func dropShadow() {
        layer.masksToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOpacity = 0.5
        layer.shadowOffset = CGSize(width: -1, height: 1)
        layer.shadowRadius = 1
        layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
        layer.shouldRasterize = true
        layer.rasterizationScale = UIScreen.main.scale
    }
}

所有这些 self. 都是不必要的。 - ThomasW

53

非常简单,只需几行代码:

let viewShadow = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
viewShadow.center = self.view.center
viewShadow.backgroundColor = UIColor.yellow
viewShadow.layer.shadowColor = UIColor.red.cgColor
viewShadow.layer.shadowOpacity = 1
viewShadow.layer.shadowOffset = CGSize.zero
viewShadow.layer.shadowRadius = 5
self.view.addSubview(viewShadow)

看起来像:在此输入图片描述


1
这个怎么能正常工作而不将 masksToBounds 设置为 false 呢? - Shivam Pokhriyal
2
@ShivamPokhriyal maskToBounds 默认为 false。 - chengsam

22

这个对我有效(适用于Swift 3和4)

yourView.layer.shadowColor = UIColor.gray.cgColor
yourView.layer.shadowOpacity = 0.3
yourView.layer.shadowOffset = CGSize.zero
yourView.layer.shadowRadius = 6

3
谢谢!如果您将第三行更改如下,那么对于第一次尝试的人来说,阴影会更加明显。 yourView.layer.shadowOffset = CGSize(width: 2, height: 2) - Ahmet Akkök
1
这个怎么能正常工作而不将 masksToBounds 设置为 false 呢? - Shivam Pokhriyal

11

非常易于使用的 UIView 扩展,可直接从故事板进行编辑。Swift 4+。

@IBDesignable extension UIView {
    @IBInspectable var shadowColor: UIColor?{
        set {
            guard let uiColor = newValue else { return }
            layer.shadowColor = uiColor.cgColor
        }
        get{
            guard let color = layer.shadowColor else { return nil }
            return UIColor(cgColor: color)
        }
    }

    @IBInspectable var shadowOpacity: Float{
        set {
            layer.shadowOpacity = newValue
        }
        get{
            return layer.shadowOpacity
        }
    }

    @IBInspectable var shadowOffset: CGSize{
        set {
            layer.shadowOffset = newValue
        }
        get{
            return layer.shadowOffset
        }
    }

    @IBInspectable var shadowRadius: CGFloat{
        set {
            layer.shadowRadius = newValue
        }
        get{
            return layer.shadowRadius
        }
    }
}

7

尽管被接受的答案很好并且按照预期工作,但我已经修改了它以将offSet: CGSize拆分为offsetX: CGFloatoffsetY: CGFloat

extension UIView {
  func dropShadow(offsetX: CGFloat, offsetY: CGFloat, color: UIColor, opacity: Float, radius: CGFloat, scale: Bool = true) {
    layer.masksToBounds = false
    layer.shadowOffset = CGSize(width: offsetX, height: offsetY)
    layer.shadowColor = color.cgColor
    layer.shadowOpacity = opacity
    layer.shadowRadius = radius
    layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
    layer.shouldRasterize = true
    layer.rasterizationScale = scale ? UIScreen.main.scale : 1
  }
}

7

Swift 5

只需调用此函数并传递您的视图即可。

public func setViewSettingWithBgShade(view: UIView)
{
    view.layer.cornerRadius = 8
    view.layer.borderWidth = 1
    view.layer.borderColor = UIColor.red.cgColor
    
    //MARK:- Shade a view
    view.layer.shadowOpacity = 0.5
    view.layer.shadowOffset = CGSize(width: 1.0, height: 1.0)
    view.layer.shadowRadius = 3.0
    view.layer.shadowColor = UIColor.black.cgColor
    view.layer.masksToBounds = false
}

4
请尝试这个。
func applyShadowOnView(_ view: UIView) {
    view.layer.cornerRadius = 8
    view.layer.shadowColor = UIColor.darkGray.cgColor
    view.layer.shadowOpacity = 1
    view.layer.shadowOffset = .zero
    view.layer.shadowRadius = 5
}

4

请尝试这个方法,我用过它并且有效。

extension UIView {

    func dropShadow() {
    
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 2, height: 3)
        layer.masksToBounds = false
    
        layer.shadowOpacity = 0.3
        layer.shadowRadius = 3
        //layer.shadowPath = UIBezierPath(rect: bounds).cgPath
        layer.rasterizationScale = UIScreen.main.scale
        layer.shouldRasterize = true
    }
}

3
对于Swift 5用户,可以这样做。
extension UIView {
  func addShadow() {
    self.layer.shadowColor = UIColor.gray.cgColor
    self.layer.shadowOffset = CGSize(width: 1, height: 1)
    self.layer.shadowOpacity = 1
  }
}

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接