简体   繁体   English

Swift - 圆角半径和阴影问题

[英]Swift - Problems with corner radius and drop shadow

I'm trying to create a button with rounded corners and a drop shadow .我正在尝试创建一个带有圆角阴影的按钮。 No matter how I switch up, the button will not display correctly.无论我如何切换,该按钮都无法正确显示。 I've tried masksToBounds = false and masksToBounds = true , but either the corner radius works and the shadow does not or the shadow works and the corner radius doesn't clip the corners of the button.我已经尝试过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
    }
}

The following Swift 5 / iOS 12 code shows how to set a subclass of UIButton that allows to create instances with rounded corners and shadow around it: 以下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
        }        
    }

}

According to your needs, you may add a UIButton in your Storyboard and set its class to CustomButton or you may create an instance of CustomButton programmatically. 根据您的需要,您可以在Storyboard中添加UIButton并将其类设置为CustomButton ,也可以以编程方式创建CustomButton实例。 The following UIViewController implementation shows how to create and use a CustomButton instance programmatically: 以下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])
    }

}

The previous code produces the image below in the iPhone simulator: 前面的代码在iPhone模拟器中生成下面的图像:

在此输入图像描述

My custom button with some shadow and rounded corners , I use it directly within the Storyboard with no need to touch it programmatically. 我的自定义按钮有一些阴影圆角 ,我直接在Storyboard使用它,无需以编程方式触摸它。

Swift 4 斯威夫特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
    }
}

在此输入图像描述

To expand on Imanou's post, it's possible to programmatically add the shadow layer in the custom button class 要扩展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)
    }
}

An alternative way to get more usable and consistent button. 获得更多可用和一致按钮的另一种方法。

Swift 2 斯威夫特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

Swift 3 斯威夫特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

Swift 5 & No need of "UIBezierPath" Swift 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

To improve PiterPan's answer and show a real shadow (not just a background with no blur) with a circular button in Swift 3: 在Swift 3中使用圆形按钮改进PiterPan的答案并显示真实的阴影(不仅仅是没有模糊的背景):

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)
}

Exact solution for 2020 syntax 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
    }
}

在此处输入图片说明

  • Note that the very old top answer here is correct but has a critical error请注意,这里非常古老的最佳答案是正确的,但有一个严重错误

Note that UIButton is unfortunately quite different from UIView in iOS.请注意,不幸的是UIButton与 iOS 中的UIView完全不同。

  • Due to a strange behavior in iOS, you must set the background color (which of course must be clear in this case) in initialization, not in layout .由于 iOS 中的一个奇怪行为,您必须在初始化而不是在 layout 中设置背景颜色(在这种情况下当然必须清楚)。 You could just set it clear in storyboard (but you usually click it to be some solid color simply so you can see it when working in storyboard.)您可以在情节提要中将其设置为清晰(但您通常单击它以使其成为某种纯色,以便在情节提要中工作时可以看到它。)

In general combos of shadows/rounding are a real pain in iOS.一般来说,阴影/圆角的组合在 iOS 中是一个真正的痛苦。 Similar solutions:类似的解决方案:

https://stackoverflow.com/a/57465440/294884 - image + rounded + shadows https://stackoverflow.com/a/57465440/294884 - 图像 + 圆角 + 阴影
https://stackoverflow.com/a/41553784/294884 - two-corner problem https://stackoverflow.com/a/41553784/294884 - 两角问题
https://stackoverflow.com/a/59092828/294884 - "shadows + hole" or "glowbox" problem https://stackoverflow.com/a/59092828/294884 - “阴影+孔”或“发光盒”问题
https://stackoverflow.com/a/57400842/294884 - the "border AND gap" problem https://stackoverflow.com/a/57400842/294884 - “边界和差距”问题
https://stackoverflow.com/a/57514286/294884 - basic "adding" beziers https://stackoverflow.com/a/57514286/294884 - 基本的“添加”贝塞尔曲线

Corner Radius with Shadow带阴影的角半径

Short and simple way !!!!!简短而简单的方法!!!!

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
        }
    }

Use of code代码的使用

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

No need maskToBound不需要 maskToBound

Please verify clipsToBounds is false.请验证 clipsToBounds 是否为假。

OUTPUT输出

在此处输入图片说明

If somebody need add shadows to rounded buttons in Swift 3.0, here is a good method to do it. 如果有人需要在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)
}

Use this method in func viewDidLayoutSubviews() as bellow: func viewDidLayoutSubviews()使用此方法如下:

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

The effect of this method is: 这种方法的效果是: 在此输入图像描述

Refactored this to support any view. 重构这个以支持任何视图。 Subclass your view from this and it should have rounded corners. 从中对视图进行子类化,它应该有圆角。 If you add something like a UIVisualEffectView as a subview to this view you likely need to use the same rounded corners on that UIVisualEffectView or it won't have rounded corners. 如果您将UIVisualEffectView作为子视图添加到此视图中,则可能需要在该UIVisualEffectView上使用相同的圆角,否则它将不具有圆角。

UIView带阴影的圆角 - 截图也使用模糊,这是一个普通的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)
        }
    }
}

Extension to drop shadow and corner radius 延伸到阴影和角半径

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)
}

}

Here is the solution that will work!这是有效的解决方案!


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
}

Finally, to apply shadow with corner radius call as per below:最后,应用具有角半径调用的阴影,如下所示:

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

Result Image结果图片

在此处输入图片说明

UPDATE : If you don't see the expected output then try calling the extension method from Main Thread , that will work for sure!更新:如果您没有看到预期的输出,请尝试从Main Thread调用扩展方法,这肯定会起作用!

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

Using CAShapeLayer and UIBezierPath we can easily add shadow and corner radius to UIView and the class derived from it like UIButton, UIImageView, UILabel etc.使用 CAShapeLayer 和 UIBezierPath,我们可以轻松地将阴影和圆角半径添加到 UIView 和从它派生的类,如 UIButton、UIImageView、UILabel 等。

We will add UIView Extension and the good point of this is, you only need to write just one line of code to achieve this.我们将添加 UIView 扩展,这样做的好处是,您只需要编写一行代码即可实现这一点。

You can round specific corner as well Just add below UIView Extension in your project:您也可以绕过特定的角落只需在您的项目中添加以下 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)
  }
}

Now just write below code to add shadow and corner radius现在只需编写下面的代码来添加阴影和圆角半径

  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)

You can create a protocol and conform it to you UIView, UIButton, Cell or whatever you want like that:您可以创建一个协议并使其符合您的 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)
    }
}

Just add the following code for corner radius and shadow,you need to give background color to the view, So the shadow doesn't affect the subviews. 只需为角半径和阴影添加以下代码,您需要为视图提供背景颜色,因此阴影不会影响子视图。

      func shadowOnviewWithcornerRadius(YourView:UIView) 
{  
        YourView.layer.shadowColor = UIColor.black.cgColor;
        YourView.layer.shadowOpacity = 0.5;
        YourView.layer.shadowRadius  = 5;
        YourView.layer.shadowOffset  = CGSize(width :0, height :0)
        YourView.layer.masksToBounds = false;
        YourView.layer.cornerRadius  =  2.0;
        YourView.layer.borderWidth   = 0.5;
        YourView.backgroundColor     = UIColor.white;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM