【问题标题】:Adding multiple shadows hides the background colour and text UIButton添加多个阴影隐藏背景颜色和文字 UIButton
【发布时间】:2020-06-02 12:02:03
【问题描述】:

我试图向我的 UIButton 添加多个阴影。正如您在图像中看到的那样,添加了两个阴影。但是,它们隐藏了 UIButton 的标题和背景颜色。为什么会这样?那么,图层的顺序是不是变成了bottomLayer、topLayer、text、background?

实际结果

预期的结果

这就是我的 UIButton 类的外观。

class PrimaryButton: UIButton {
    
    let cornerRadius: CGFloat = 10
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    convenience init() {
        self.init(frame: .zero)
        configure()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        addDropShadow()
    }
    
    private func configure() {
        backgroundColor = .white;
        layer.cornerRadius = cornerRadius
        
        setTitle("Get Followers", for: .normal)
        setTitleColor(Colours.buttonTextColour, for: .normal)
    }

    private func addDropShadow() {
        let topLayer = createShadowLayer(color: Colours.shadowWhite, offset: CGSize(width: -6, height: -6))
        let bottomLayer = createShadowLayer(color: Colours.shadowBlack, offset: CGSize(width: 6, height: 6))
        
        layer.addSublayer(topLayer)
        layer.addSublayer(bottomLayer)
    }
    
    private func createShadowLayer(color: UIColor, offset: CGSize) -> CALayer {
        let shadowLayer = CALayer()
        shadowLayer.masksToBounds = false
        shadowLayer.shadowColor = color.cgColor
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = offset
        shadowLayer.shadowRadius = 10
        shadowLayer.shouldRasterize = true
        shadowLayer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 10).cgPath
        
        return shadowLayer
    }
    
}

【问题讨论】:

标签: swift uibutton swift4 swift5


【解决方案1】:

我能够通过以下方式解决问题:

我没有使用addSublayer(_ layer: CALayer) 方法添加层,而是使用insertSublayer(_ layer: CALayer, at idx: UInt32) 方法。

private func addDropShadow() {
        let topLayer = createShadowLayer(color: Colours.shadowWhite, offset: CGSize(width: -6, height: -6))
        let bottomLayer = createShadowLayer(color: Colours.shadowBlack, offset: CGSize(width: 6, height: 6))

        // Modified
        layer.insertSublayer(topLayer, at: 0)
        layer.insertSublayer(bottomLayer, at: 0)
    }

另外,在您的 createShadowLayer 方法中,我返回了一个 CAShapeLayer,而不是 CALayer。

private func createShadowLayer(color: UIColor, offset: CGSize) -> CAShapeLayer {
        // Modified
        let shadowLayer = CAShapeLayer()
        shadowLayer.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.cornerRadius).cgPath
        shadowLayer.fillColor = self.backgroundColor?.cgColor
        shadowLayer.shadowPath = shadowLayer.path
        
//        shadowLayer.masksToBounds = false
        shadowLayer.shadowColor = color.cgColor
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = offset
        shadowLayer.shadowRadius = 10
//        shadowLayer.shouldRasterize = true

        return shadowLayer
    }

我不知道这两种改变是否必不可少。但这就是它对我有用的方式:)

【讨论】:

    【解决方案2】:

    您好,下面的代码会帮助您,我在按钮阴影中得到了您想要的确切结果

    只需用我的代码替换一些函数,

    您的代码:

    override func layoutSubviews() {
    
        super.layoutSubviews()
        addDropShadow()
    }
    

    用我的代码替换它:

     override func layoutSubviews() {
            super.layoutSubviews()
            addDropShadow(color: UIColor.red, offset: CGSize(width: -6, height: -6), btnLayer: self.layer)
            addDropShadow(color: UIColor.blue, offset: CGSize(width: 6, height: 6), btnLayer: self.layer)
        }
    

    您的代码:

     private func addDropShadow() {
            let topLayer = createShadowLayer(color: Colours.shadowWhite, offset: CGSize(width: -6, height: -6))
            let bottomLayer = createShadowLayer(color: Colours.shadowBlack, offset: CGSize(width: 6, height: 6))
    
        layer.addSublayer(topLayer)
        layer.addSublayer(bottomLayer)
    }
    
    private func createShadowLayer(color: UIColor, offset: CGSize) -> CALayer {
        let shadowLayer = CALayer()
        shadowLayer.masksToBounds = false
        shadowLayer.shadowColor = color.cgColor
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = offset
        shadowLayer.shadowRadius = 10
        shadowLayer.shouldRasterize = true
        shadowLayer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 10).cgPath
    
        return shadowLayer
    }
    

    用下面的代码替换它:

     private func addDropShadow(color: UIColor, offset: CGSize, btnLayer : CALayer)
        {
    
            btnLayer.masksToBounds = false
            btnLayer.shadowColor = color.cgColor
            btnLayer.shadowOpacity = 1
            btnLayer.shadowOffset = offset
            btnLayer.shadowRadius = 10
    
        }
    

    不需要你private func createShadowLayer(color: UIColor, offset: CGSize) -> CALayer

    您可以删除该功能。

    并确保您的按钮类型是自定义的

    【讨论】:

    • 嗯...我无法得到预期的结果。两次设置阴影属性如何渲染两个阴影?
    • 你只是用第二个阴影覆盖了第一个阴影,并没有绘制两个阴影。
    猜你喜欢
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 2020-06-21
    • 2023-02-21
    • 1970-01-01
    相关资源
    最近更新 更多