UIButton调用setTitle方法后自定义字体被重置为系统默认如何解决
问题原因
调用setTitle(_:for:)时,UIKit会为对应状态生成默认属性的文本,覆盖你直接对titleLabel.font的设置。如果你后续还需要动态修改按钮标题,仅调整初始化时的代码执行顺序无法彻底解决问题。
解决方案
方案1:重写setTitle方法(全iOS版本兼容,支持后续动态修改标题)
新增自定义字体存储属性,重写setTitle方法保证每次设置标题后字体都能生效,完整代码如下:
class RoundedButton: UIButton { // 存储自定义字体,修改时自动更新 var customFont: UIFont = .customFont16 { didSet { titleLabel?.font = customFont } } override init(frame: CGRect) { super.init(frame: frame) styleButton() } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) styleButton() } func styleButton(title: String = "button", font: UIFont = .customFont16) { self.customFont = font self.backgroundColor = .yellow self.setTitle(title, for: .normal) } // 重写设置标题方法,设置完成后重新赋值字体 override func setTitle(_ title: String?, for state: UIControl.State) { super.setTitle(title, for: state) titleLabel?.font = customFont } }
方案2:使用属性文本设置标题(无需重写方法,适合不需要动态修改标题的场景)
直接把字体写入属性文本中,设置到对应按钮状态即可,无需担心被系统重置:
func styleButton(title: String = "button", font: UIFont = .customFont16) { self.backgroundColor = .yellow // 构造带自定义字体的属性文本 let attributes: [NSAttributedString.Key: Any] = [.font: font] let attributedTitle = NSAttributedString(string: title, attributes: attributes) // 给需要的状态设置属性文本,所有状态都可复用该属性文本实现字体统一 self.setAttributedTitle(attributedTitle, for: .normal) self.setAttributedTitle(attributedTitle, for: .highlighted) self.setAttributedTitle(attributedTitle, for: .disabled) }
方案3:iOS15+使用Configuration配置(系统原生推荐方案)
iOS15之后UIButton推出了Configuration配置体系,不需要处理属性覆盖问题,配置更简洁:
@available(iOS 15.0, *) func styleButton(title: String = "button", font: UIFont = .customFont16) { var config = UIButton.Configuration.filled() config.title = title config.baseBackgroundColor = .yellow // 统一配置标题文本属性 config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attributes in var newAttributes = attributes newAttributes.font = font return newAttributes } self.configuration = config }
内容的提问来源于stack exchange,提问作者AVR
相关产品推荐
相关产品推荐

