You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过UIButton Configuration新方式为iOS按钮添加阴影?

在UIButton.Configuration模式下添加阴影

使用新的Configuration样式时,依然可以通过按钮的layer属性设置阴影,只需注意两个核心要点:

  • 必须将layer.masksToBounds设为false,否则阴影会被按钮边界裁剪
  • 同步layer.cornerRadius与Configuration中设置的cornerStyle,保证阴影圆角与按钮圆角匹配

修改后的按钮实现代码

public class MainButton: UIButton {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    private func setup() {
        var config = UIButton.Configuration.borderedTinted()
        config.baseBackgroundColor = .red
        config.buttonSize = .medium
        config.cornerStyle = .capsule

        let handler: UIButton.ConfigurationUpdateHandler = { [self] button in
            switch button.state {
            case .highlighted:
                button.configuration?.baseBackgroundColor = .blue
                // 高亮时调整阴影(可选)
                layer.shadowOffset = CGSize(width: 0, height: 1)
                layer.shadowOpacity = 0.2
            default:
                button.configuration?.baseBackgroundColor = .red
                // 恢复默认阴影
                layer.shadowOffset = CGSize(width: 0, height: 2)
                layer.shadowOpacity = 0.3
            }
            // 状态变化时同步圆角
            syncCornerRadius(with: button.configuration?.cornerStyle)
        }

        config.titleTextAttributesTransformer =
        UIConfigurationTextAttributesTransformer { [self] incoming in
            var outgoing = incoming
            outgoing.font = UIFont().withSize(16)
            outgoing.foregroundColor = isEnabled ? .white : .gray
            return outgoing
        }

        config.contentInsets = .init(top: 4, leading: 4, bottom: 4, trailing: 4)
        configuration = config
        configurationUpdateHandler = handler

        // 初始化阴影设置
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2)
        layer.shadowOpacity = 0.3
        layer.shadowRadius = 4
        layer.masksToBounds = false
        // 初始同步圆角
        syncCornerRadius(with: config.cornerStyle)
    }

    // 同步layer圆角与Configuration的cornerStyle
    private func syncCornerRadius(with cornerStyle: UIButton.Configuration.CornerStyle?) {
        guard let cornerStyle = cornerStyle else { return }
        switch cornerStyle {
        case .capsule:
            // 胶囊样式根据按钮高度动态计算圆角
            layer.cornerRadius = bounds.height / 2
        case .large, .medium, .small:
            // 使用系统提供的对应圆角值
            layer.cornerRadius = cornerStyle.cornerRadius(for: self)
        default:
            layer.cornerRadius = 0
        }
    }

    override var isEnabled: Bool {
        didSet {
            var updatedConfiguration = self.configuration
            updatedConfiguration?.background.backgroundColor = .clear
            self.configuration = updatedConfiguration
            // 状态变化时同步圆角
            syncCornerRadius(with: updatedConfiguration?.cornerStyle)
        }
    }

    // 按钮布局变化时重新计算胶囊样式的圆角
    override func layoutSubviews() {
        super.layoutSubviews()
        if configuration?.cornerStyle == .capsule {
            layer.cornerRadius = bounds.height / 2
        }
    }
}

关键说明

  • 封装syncCornerRadius方法,确保初始化、状态变化、布局更新时,layer圆角始终与Configuration的cornerStyle一致
  • 可在configurationUpdateHandler中根据按钮状态(如高亮、禁用)调整阴影参数,实现交互反馈
  • 在layoutSubviews中重新计算胶囊样式的圆角,避免按钮尺寸变化后圆角不匹配

内容的提问来源于stack exchange,提问作者Martin Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:40:24