如何通过UIButton Configuration新方式为iOS按钮添加阴影?
使用新的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
相关产品推荐
相关产品推荐

