【问题标题】:Swift - Problems with corner radius and drop shadowSwift - 圆角半径和阴影问题
【发布时间】:2014-08-29 22:54:58
【问题描述】:

我正在尝试创建一个带有圆角阴影的按钮。无论我如何切换,按钮都不会正确显示。我试过masksToBounds = falsemasksToBounds = true,但要么圆角半径起作用,阴影不起作用,要么阴影起作用,圆角半径不剪裁按钮的角。

import UIKit
import QuartzCore

@IBDesignable
class Button : UIButton
{
    @IBInspectable var masksToBounds: Bool    = false                {didSet{updateLayerProperties()}}
    @IBInspectable var cornerRadius : CGFloat = 0                    {didSet{updateLayerProperties()}}
    @IBInspectable var borderWidth  : CGFloat = 0                    {didSet{updateLayerProperties()}}
    @IBInspectable var borderColor  : UIColor = UIColor.clearColor() {didSet{updateLayerProperties()}}
    @IBInspectable var shadowColor  : UIColor = UIColor.clearColor() {didSet{updateLayerProperties()}}
    @IBInspectable var shadowOpacity: CGFloat = 0                    {didSet{updateLayerProperties()}}
    @IBInspectable var shadowRadius : CGFloat = 0                    {didSet{updateLayerProperties()}}
    @IBInspectable var shadowOffset : CGSize  = CGSizeMake(0, 0)     {didSet{updateLayerProperties()}}

    override func drawRect(rect: CGRect)
    {
        updateLayerProperties()
    }

    func updateLayerProperties()
    {
        self.layer.masksToBounds = masksToBounds
        self.layer.cornerRadius = cornerRadius
        self.layer.borderWidth = borderWidth
        self.layer.borderColor = borderColor.CGColor
        self.layer.shadowColor = shadowColor.CGColor
        self.layer.shadowOpacity = CFloat(shadowOpacity)
        self.layer.shadowRadius = shadowRadius
        self.layer.shadowOffset = shadowOffset
    }
}

【问题讨论】:

  • 您需要将阴影和剪辑放在不同的图层上。在drawRect 中设置图层属性并不是一个好主意。最好把它们放在initWithCoder
  • 对于任何在这里搜索的人来说,就像经常遇到非常古老的问题一样,这里的最佳答案虽然通常是正确的现在有一些严重错误。 (我输入了一个更正的答案。)大多数人,尤其是我,盲目地从顶部 SO 答案复制和粘贴 - 如果它是一个非常的 QA,请小心! (现在是 2020 年 - 5 年后必须有人取代我的答案!)
  • 如果您的按钮有图像,那么您需要添加角半径以及按钮的 imageView。这将是最简单的方法

标签: ios swift shadow xcode6 cornerradius


【解决方案1】:

以下 Swift 5 / iOS 12 代码展示了如何设置 UIButton 的子类,以允许创建带有圆角和阴影的实例:

import UIKit

final class CustomButton: UIButton {

    private var shadowLayer: CAShapeLayer!

    override func layoutSubviews() {
        super.layoutSubviews()

        if shadowLayer == nil {
            shadowLayer = CAShapeLayer()
            shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
            shadowLayer.fillColor = UIColor.white.cgColor

            shadowLayer.shadowColor = UIColor.darkGray.cgColor
            shadowLayer.shadowPath = shadowLayer.path
            shadowLayer.shadowOffset = CGSize(width: 2.0, height: 2.0)
            shadowLayer.shadowOpacity = 0.8
            shadowLayer.shadowRadius = 2

            layer.insertSublayer(shadowLayer, at: 0)
            //layer.insertSublayer(shadowLayer, below: nil) // also works
        }        
    }

}

根据您的需要,您可以在 Storyboard 中添加UIButton 并将其类设置为CustomButton,或者您可以通过编程方式创建CustomButton 的实例。以下UIViewController 实现展示了如何以编程方式创建和使用CustomButton 实例:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = CustomButton(type: .system)
        button.setTitle("Button", for: .normal)
        view.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false
        let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)        
        let widthConstraint = button.widthAnchor.constraint(equalToConstant: 100)
        let heightConstraint = button.heightAnchor.constraint(equalToConstant: 100)
        NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
    }

}

前面的代码在 iPhone 模拟器中生成下面的图像:

【讨论】:

  • 对于 iOS,我的旧实现有问题,现在它可以工作了。谢谢!
  • 如何从主视图控制器@POB 调用该类?
  • 有没有办法修剪阴影层,只保留可见部分?
  • 由于shadowlayer是button自身layer的子layer,有masksToBounds = YES显示圆角,不也剪掉阴影吗?
  • 效果很好,但我无法再更改按钮背景了。这可能是因为 shadowLayer.fillColor。你有什么建议?谢谢!
【解决方案2】:

我的自定义按钮带有一些阴影圆角,我直接在Storyboard中使用它,无需以编程方式触摸

斯威夫特 4

class RoundedButtonWithShadow: UIButton {
    override func awakeFromNib() {
        super.awakeFromNib()
        self.layer.masksToBounds = false
        self.layer.cornerRadius = self.frame.height/2
        self.layer.shadowColor = UIColor.black.cgColor
        self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath
        self.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
        self.layer.shadowOpacity = 0.5
        self.layer.shadowRadius = 1.0
    }
}

【讨论】:

  • 快速简单。
  • 对我来说,当我将代码重新放入 layoutSubviews() 时,它就成功了。
【解决方案3】:

要扩展 Imanou 的帖子,可以在自定义按钮类中以编程方式添加阴影层

@IBDesignable class CustomButton: UIButton {
    var shadowAdded: Bool = false

    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)

        if shadowAdded { return }
        shadowAdded = true

        let shadowLayer = UIView(frame: self.frame)
        shadowLayer.backgroundColor = UIColor.clearColor()
        shadowLayer.layer.shadowColor = UIColor.darkGrayColor().CGColor
        shadowLayer.layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: self.cornerRadius).CGPath
        shadowLayer.layer.shadowOffset = CGSize(width: 1.0, height: 1.0)
        shadowLayer.layer.shadowOpacity = 0.5
        shadowLayer.layer.shadowRadius = 1
        shadowLayer.layer.masksToBounds = true
        shadowLayer.clipsToBounds = false

        self.superview?.addSubview(shadowLayer)
        self.superview?.bringSubviewToFront(self)
    }
}

【讨论】:

  • 你正在掩盖图层的阴影,我真的不建议将阴影视图放在按钮的超级视图上。
【解决方案4】:

获得更多可用和一致的按钮的另一种方法。

斯威夫特 2:

func getImageWithColor(color: UIColor, size: CGSize, cornerRadius:CGFloat) -> UIImage {
    let rect = CGRectMake(0, 0, size.width, size.height)
    UIGraphicsBeginImageContextWithOptions(size, false, 1)
    UIBezierPath(
        roundedRect: rect,
        cornerRadius: cornerRadius
        ).addClip()
    color.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}

let button = UIButton(type: .Custom)
button.frame = CGRectMake(20, 20, 200, 50)
button.setTitle("My Button", forState: UIControlState.Normal)
button.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
self.addSubview(button)

let image = getImageWithColor(UIColor.whiteColor(), size: button.frame.size, cornerRadius: 5)
button.setBackgroundImage(image, forState: UIControlState.Normal)

button.layer.shadowRadius = 5
button.layer.shadowColor = UIColor.blackColor().CGColor
button.layer.shadowOpacity = 0.5
button.layer.shadowOffset = CGSizeMake(0, 1)
button.layer.masksToBounds = false

斯威夫特 3:

func getImageWithColor(_ color: UIColor, size: CGSize, cornerRadius:CGFloat) -> UIImage? {
    let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    color.setFill()
    UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
    color.setFill()
    UIRectFill(rect)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return image
}

let button = UIButton(type: .custom)
button.frame = CGRect(x:20, y:20, width:200, height:50)
button.setTitle("My Button", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
self.addSubview(button)

if let image = getImageWithColor(UIColor.white, size: button.frame.size, cornerRadius: 5) {
    button.setBackgroundImage(image, for: .normal)
}

button.layer.shadowRadius = 5
button.layer.shadowColor = UIColor.black.cgColor
button.layer.shadowOpacity = 0.5
button.layer.shadowOffset = CGSize(width:0, height:1)
button.layer.masksToBounds = false

【讨论】:

  • 此方法最好,因为您可以为 .normal 和突出显示设置不同的背景颜色
  • 不错。尝试了许多不同的方法来获取按钮中的背景颜色、圆角半径和阴影,但这是唯一可行的方法!谢谢!
  • 这是完美的解决方案,谢谢!请注意,如果在 UITableViewCell 中使用 UIButton,则必须以编程方式将其放置在 layoutSubviews() 中。
  • 有一个问题,当我在iPhone 5s(iOS 12.4)模拟器上测试时,按钮标题颜色没有生效,一直是白色的。不幸的是,我没有具有相同 iOS 版本的实际设备来测试这一点。我必须将它转移到 layoutSubviews 才能工作。不完全确定原因。
【解决方案5】:

斯威夫特 5 & 不需要“UIBezierPath”

    view.layer.cornerRadius = 15
    view.clipsToBounds = true
    view.layer.masksToBounds = false
    view.layer.shadowRadius = 7
    view.layer.shadowOpacity = 0.6
    view.layer.shadowOffset = CGSize(width: 0, height: 5)
    view.layer.shadowColor = UIColor.red.cgColor

【讨论】:

  • 它从不向视图添加任何角半径,您需要UIBezierPath 的原因是出于性能原因,以防您需要重用该特定视图。
  • @SharkesMonken “绝不”真的!!!! ?请再次检查。我在整个项目中都使用这种方法。如果您有任何疑问,请查看此视频youtu.be/5qdF5ocDU7w
  • 请看视频
  • 如果您有按钮的背景图像,则它不起作用。图像角半径未设置
  • @SharkesMonken 我正在寻找一些关于阴影的解决方案,看看我在这里找到的是你的评论??很高兴见到你,伙计。
【解决方案6】:

重构 this 以支持任何视图。从这个子类你的视图,它应该有圆角。如果您将 UIVisualEffectView 之类的内容作为子视图添加到此视图,您可能需要在该 UIVisualEffectView 上使用相同的圆角,否则它不会有圆角。

/// Inspiration: https://stackoverflow.com/a/25475536/129202
class ViewWithRoundedcornersAndShadow: UIView {
    private var theShadowLayer: CAShapeLayer?

    override func layoutSubviews() {
        super.layoutSubviews()

        if self.theShadowLayer == nil {
            let rounding = CGFloat.init(22.0)

            let shadowLayer = CAShapeLayer.init()
            self.theShadowLayer = shadowLayer
            shadowLayer.path = UIBezierPath.init(roundedRect: bounds, cornerRadius: rounding).cgPath
            shadowLayer.fillColor = UIColor.clear.cgColor

            shadowLayer.shadowPath = shadowLayer.path
            shadowLayer.shadowColor = UIColor.black.cgColor
            shadowLayer.shadowRadius = CGFloat.init(3.0)
            shadowLayer.shadowOpacity = Float.init(0.2)
            shadowLayer.shadowOffset = CGSize.init(width: 0.0, height: 4.0)

            self.layer.insertSublayer(shadowLayer, at: 0)
        }
    }
}

【讨论】:

    【解决方案7】:

    为了改进 PiterPan 的答案并在 Swift 3 中使用圆形按钮显示真实的阴影(不仅仅是没有模糊的背景):

    override func viewDidLoad() {
        super.viewDidLoad()
        myButton.layer.masksToBounds = false
        myButton.layer.cornerRadius = myButton.frame.height/2
        myButton.clipsToBounds = true
    }
    
    override func viewDidLayoutSubviews() {
        addShadowForRoundedButton(view: self.view, button: myButton, opacity: 0.5)
    }
    
    func addShadowForRoundedButton(view: UIView, button: UIButton, opacity: Float = 1) {
        let shadowView = UIView()
        shadowView.backgroundColor = UIColor.black
        shadowView.layer.opacity = opacity
        shadowView.layer.shadowRadius = 5
        shadowView.layer.shadowOpacity = 0.35
        shadowView.layer.shadowOffset = CGSize(width: 0, height: 0)
        shadowView.layer.cornerRadius = button.bounds.size.width / 2
        shadowView.frame = CGRect(origin: CGPoint(x: button.frame.origin.x, y: button.frame.origin.y), size: CGSize(width: button.bounds.width, height: button.bounds.height))
        self.view.addSubview(shadowView)
        view.bringSubview(toFront: button)
    }
    

    【讨论】:

      【解决方案8】:

      带阴影的拐角半径

      简单的方法!!!!!!

      extension CALayer {
          func applyCornerRadiusShadow(
              color: UIColor = .black,
              alpha: Float = 0.5,
              x: CGFloat = 0,
              y: CGFloat = 2,
              blur: CGFloat = 4,
              spread: CGFloat = 0,
              cornerRadiusValue: CGFloat = 0)
          {
              cornerRadius = cornerRadiusValue
              shadowColor = color.cgColor
              shadowOpacity = alpha
              shadowOffset = CGSize(width: x, height: y)
              shadowRadius = blur / 2.0
              if spread == 0 {
                  shadowPath = nil
              } else {
                  let dx = -spread
                  let rect = bounds.insetBy(dx: dx, dy: dx)
                  shadowPath = UIBezierPath(rect: rect).cgPath
              }
          }
      

      代码的使用

      btn.layer.applyCornerRadiusShadow(color: .black, 
                                  alpha: 0.38, 
                                  x: 0, y: 3, 
                                  blur: 10, 
                                  spread: 0, 
                                  cornerRadiusValue: 24)
      

      不需要 maskToBound

      请验证 clipsToBounds 是否为假。

      输出

      【讨论】:

      • 感谢您提供的代码,但对我不起作用,为什么?请查看图片:imgur.com/dY5M3BL
      • @Mc.Lover 你用过 maskToBound 吗?还是 clipsToBounds?
      【解决方案9】:

      2020 语法的准确解决方案

      import UIKit
      class ColorAndShadowButton: UIButton {
          override init(frame: CGRect) { super.init(frame: frame), common() }
          required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder), common() }
          private func common() {
              // UIButton is tricky: you MUST set the clear bg in bringup;  NOT in layout
              backgroundColor = .clear
              clipsToBounds = false
              self.layer.insertSublayer(colorAndShadow, below: layer)
          }
          
         lazy var colorAndShadow: CAShapeLayer = {
              let s = CAShapeLayer()
              // set your button color HERE (NOT on storyboard)
              s.fillColor = UIColor.black.cgColor
              // now set your shadow color/values
              s.shadowColor = UIColor.red.cgColor
              s.shadowOffset = CGSize(width: 0, height: 10)
              s.shadowOpacity = 1
              s.shadowRadius = 10
              // now add the shadow
              layer.insertSublayer(s, at: 0)
              return s
          }()
          
          override func layoutSubviews() {
              super.layoutSubviews()
              // you MUST layout these two EVERY layout cycle:
              colorAndShadow.frame = bounds
              colorAndShadow.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
          }
      }
      

      • 请注意,这里非常古老的最佳答案是正确的,但有一个严重错误

      请注意,UIButton 很遗憾与 iOS 中的 UIView 完全不同。

      • 由于 iOS 中的一个奇怪行为,您必须在初始化时设置背景颜色(在这种情况下当然必须清楚)在初始化中,而不是在布局中。您可以在故事板中将其设置为清晰(但您通常单击它以使其成为纯色,以便在故事板中工作时可以看到它。)

      一般来说,阴影/圆角的组合在 iOS 中是一件很痛苦的事情。类似的解决方案:

      https://stackoverflow.com/a/57465440/294884 - 图像 + 圆角 + 阴影
      https://stackoverflow.com/a/41553784/294884 - 两角问题
      https://stackoverflow.com/a/59092828/294884 - “阴影 + 孔”或“发光盒”问题
      https://stackoverflow.com/a/57400842/294884 - “边框” AND 间隙”问题
      https://stackoverflow.com/a/57514286/294884 - 基本的“添加”贝塞尔曲线

      【讨论】:

      • 什么是backgroundAndShadow
      • 对不起应该是 colorAndShadow 我想,改了
      【解决方案10】:

      投影和圆角半径的扩展

      extension UIView {
      
      func dropShadow(color: UIColor, opacity: Float = 0.5, offSet: CGSize, shadowRadius: CGFloat = 1, scale: Bool = true, cornerRadius: CGFloat) {
          let shadowLayer = CAShapeLayer()
          shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
          shadowLayer.fillColor = UIColor.white.cgColor
          shadowLayer.shadowColor = color.cgColor
          shadowLayer.shadowPath = shadowLayer.path
          shadowLayer.shadowOffset = offSet
          shadowLayer.shadowOpacity = opacity
          shadowLayer.shadowRadius = shadowRadius
          layer.insertSublayer(shadowLayer, at: 0)
      }
      
      }
      

      【讨论】:

        【解决方案11】:

        使用 CAShapeLayer 和 UIBezierPath 我们可以轻松地为 UIView 以及从它派生的类(如 UIButton、UIImageView、UILabel 等)添加阴影和圆角半径。

        我们将添加 UIView 扩展,这样做的好处是,您只需要编写一行代码即可实现。

        您也可以圆特定的角落只需在您的项目中添加以下 UIView 扩展:

         extension UIView {
        
          func addShadow(shadowColor: UIColor, offSet: CGSize, opacity: Float, shadowRadius: 
          CGFloat, cornerRadius: CGFloat, corners: UIRectCorner, fillColor: UIColor = .white) {
        
            let shadowLayer = CAShapeLayer()
            let size = CGSize(width: cornerRadius, height: cornerRadius)
            let cgPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: size).cgPath //1
            shadowLayer.path = cgPath //2
            shadowLayer.fillColor = fillColor.cgColor //3
            shadowLayer.shadowColor = shadowColor.cgColor //4
            shadowLayer.shadowPath = cgPath
            shadowLayer.shadowOffset = offSet //5
            shadowLayer.shadowOpacity = opacity
            shadowLayer.shadowRadius = shadowRadius
            self.layer.addSublayer(shadowLayer)
          }
        }
        

        现在只需编写下面的代码来添加阴影和圆角半径

          self.myView.addShadow(shadowColor: .black, offSet: CGSize(width: 2.6, height: 2.6), 
          opacity: 0.8, shadowRadius: 5.0, cornerRadius: 20.0, corners: [.topRight, .topLeft], 
          fillColor: .red)
        

        【讨论】:

          【解决方案12】:

          这是可行的解决方案!

          
          extension UIView {
          
              func applyShadowWithCornerRadius(color:UIColor, opacity:Float, radius: CGFloat, edge:AIEdge, shadowSpace:CGFloat)    {
          
                  var sizeOffset:CGSize = CGSize.zero
                  switch edge {
                  case .Top:
                      sizeOffset = CGSize(width: 0, height: -shadowSpace)
                  case .Left:
                      sizeOffset = CGSize(width: -shadowSpace, height: 0)
                  case .Bottom:
                      sizeOffset = CGSize(width: 0, height: shadowSpace)
                  case .Right:
                      sizeOffset = CGSize(width: shadowSpace, height: 0)
          
          
                  case .Top_Left:
                      sizeOffset = CGSize(width: -shadowSpace, height: -shadowSpace)
                  case .Top_Right:
                      sizeOffset = CGSize(width: shadowSpace, height: -shadowSpace)
                  case .Bottom_Left:
                      sizeOffset = CGSize(width: -shadowSpace, height: shadowSpace)
                  case .Bottom_Right:
                      sizeOffset = CGSize(width: shadowSpace, height: shadowSpace)
          
          
                  case .All:
                      sizeOffset = CGSize(width: 0, height: 0)
                  case .None:
                      sizeOffset = CGSize.zero
                  }
          
                  self.layer.cornerRadius = self.frame.size.height / 2
                  self.layer.masksToBounds = true;
          
                  self.layer.shadowColor = color.cgColor
                  self.layer.shadowOpacity = opacity
                  self.layer.shadowOffset = sizeOffset
                  self.layer.shadowRadius = radius
                  self.layer.masksToBounds = false
          
                  self.layer.shadowPath = UIBezierPath(roundedRect:self.bounds, cornerRadius:self.layer.cornerRadius).cgPath
              }
          }
          
          enum AIEdge:Int {
              case
              Top,
              Left,
              Bottom,
              Right,
              Top_Left,
              Top_Right,
              Bottom_Left,
              Bottom_Right,
              All,
              None
          }
          

          最后,按如下方式应用具有圆角半径调用的阴影:

          viewRounded.applyShadowWithCornerRadius(color: .gray, opacity: 1, radius: 15, edge: AIEdge.All, shadowSpace: 15)
          
          

          结果图片

          更新:如果您没有看到预期的输出,请尝试从 主线程 调用扩展方法,这肯定会起作用!

          DispatchQueue.main.async {
              viewRounded.applyShadowWithCornerRadius(color: .gray, opacity: 1, radius: 15, edge: AIEdge.All, shadowSpace: 15)
          }
          

          【讨论】:

            【解决方案13】:

            如果有人需要在 Swift 3.0 中为 圆角 按钮添加阴影,这是一个很好的方法。

            func addShadowForRoundedButton(view: UIView, button: UIButton, shadowColor: UIColor, shadowOffset: CGSize, opacity: Float = 1) {
                let shadowView = UIView()
                shadowView.backgroundColor = shadowColor
                shadowView.layer.opacity = opacity
                shadowView.layer.cornerRadius = button.bounds.size.width / 2
                shadowView.frame = CGRect(origin: CGPoint(x: button.frame.origin.x + shadowOffset.width, y: button.frame.origin.y + shadowOffset.height), size: CGSize(width: button.bouds.width, height: button.bounds.height))
                self.view.addSubview(shadowView)
                view.bringSubview(toFront: button)
            }
            

            func viewDidLayoutSubviews() 中使用此方法如下:

            override func viewDidLayoutSubviews() {
                addShadowForRoundedButton(view: self.view, button: button, shadowColor: .black, shadowOffset: CGSize(width: 2, height: 2), opacity: 0.5)
            }
            

            这种方法的效果是:

            【讨论】:

              【解决方案14】:

              您可以创建一个协议并使其符合您的 UIView、UIButton、Cell 或任何您想要的:

              protocol RoundedShadowable: class {
                  var shadowLayer: CAShapeLayer? { get set }
                  var layer: CALayer { get }
                  var bounds: CGRect { get }
              }
              ​
              extension RoundedShadowable {
                  func applyShadowOnce(withCornerRadius cornerRadius: CGFloat, andFillColor fillColor: UIColor) {
                      if self.shadowLayer == nil {
                          let shadowLayer = CAShapeLayer()
                          shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
                          shadowLayer.fillColor = fillColor.cgColor
                          shadowLayer.shadowColor = UIColor.black.cgColor
                          shadowLayer.shadowPath = shadowLayer.path
                          shadowLayer.shadowOffset = CGSize(width: 0.0, height: 2.0)
                          shadowLayer.shadowOpacity = 0.2
                          shadowLayer.shadowRadius = 3
                          self.layer.insertSublayer(shadowLayer, at: 0)
                          self.shadowLayer = shadowLayer
                      }
                  }
              }
              ​
              class RoundShadowView: UIView, RoundedShadowable {
              
                  var shadowLayer: CAShapeLayer?
                  private let cornerRadius: CGFloat
                  private let fillColor: UIColor
              
                  init(cornerRadius: CGFloat, fillColor: UIColor) {
                      self.cornerRadius = cornerRadius
                      self.fillColor = fillColor
                      super.init(frame: .zero)
                  }
              
                  required init?(coder: NSCoder) {
                      fatalError("init(coder:) has not been implemented")
                  }
              
                  override func layoutSubviews() {
                      super.layoutSubviews()
                      self.applyShadowOnce(withCornerRadius: self.cornerRadius, andFillColor: self.fillColor)
                  }
              }
              ​
              class RoundShadowButton: UIButton, RoundedShadowable {
              
                  var shadowLayer: CAShapeLayer?
                  private let cornerRadius: CGFloat
                  private let fillColor: UIColor
              
                  init(cornerRadius: CGFloat, fillColor: UIColor) {
                      self.cornerRadius = cornerRadius
                      self.fillColor = fillColor
                      super.init(frame: .zero)
                  }
              
                  required init?(coder: NSCoder) {
                      fatalError("init(coder:) has not been implemented")
                  }
              
                  override func layoutSubviews() {
                      super.layoutSubviews()
                      self.applyShadowOnce(withCornerRadius: self.cornerRadius, andFillColor: self.fillColor)
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-05-19
                • 2021-06-16
                • 2018-05-26
                • 2011-08-05
                • 1970-01-01
                相关资源
                最近更新 更多