UIButton自定义子类TakesContainerButton点击时字体异常变更问题
问题根因
该字体切换问题是自定义按钮的字体配置仅在初始化时执行一次,未覆盖按钮所有状态切换、布局更新场景导致:
- UIButton在状态(高亮/选中/普通)切换时,若未显式为所有状态指定自定义字体,会自动 fallback 到系统默认字体
- 调用
setTitleColor等修改标题属性的方法时,若之前使用了富文本标题,会重置标题的字体配置 - Stack View布局更新触发按钮重绘时,也可能丢失单次设置的字体属性
解决方案
方案1:重写布局方法保证字体配置不丢失
在自定义TakesContainerButton类中重写layoutSubviews,每次布局更新时重新设置字体:
override func layoutSubviews() { super.layoutSubviews() setFont() }
方案2:显式为所有按钮状态设置字体
修改setFont方法,为按钮所有可能的状态统一设置自定义字体,避免状态切换时的字体 fallback:
func setFont(){ guard let customFont = UIFont(name: "Lato-Bold", size: 12) else { return } self.titleLabel?.font = customFont // 覆盖所有控制状态的字体配置 let states: [UIControl.State] = [.normal, .highlighted, .selected, .disabled] for state in states { if let originTitle = self.title(for: state) { let attrTitle = NSAttributedString(string: originTitle, attributes: [.font: customFont]) self.setAttributedTitle(attrTitle, for: state) } } }
附加配置检查
确认Storyboard中按钮的类型设置为Custom而非System,System类型的按钮会自带系统样式修改逻辑,容易覆盖自定义的字体、颜色配置。
附加优化建议
你当前的下划线视图bottom每次点击都会重新创建,重复点击同一个按钮会出现视图重复添加的问题,可调整为懒加载实现,减少不必要的视图创建:
class TakesContainerButton: UIButton { // 改为懒加载,仅创建一次 lazy var bottom: UIView = { let view = UIView() view.layer.cornerRadius = 1.5 view.backgroundColor = .darkGray view.isHidden = true return view }() func click(){ self.setTitleColor(.darkGray, for: .normal) let xOffset:CGFloat = 10 bottom.frame = CGRect(x: xOffset / 2, y: self.frame.height - 3, width: self.frame.width - xOffset, height: 3) if bottom.superview == nil { self.addSubview(bottom) } bottom.isHidden = false } func unclick(){ bottom.isHidden = true self.setTitleColor(UIColor(hex: "8B8B8B"), for: .normal) } // 其余原有代码保持不变 }
内容的提问来源于stack exchange,提问作者tHatpart
相关产品推荐
相关产品推荐

