重写UILabel的font属性致标签截断,为何添加setup方法可修复?
为什么修复后的自定义
UILabel代码解决了文本截断问题? 咱们先拆解你最初代码的问题根源,再看修复方案为什么有效:
最初代码的问题
@IBDesignable class FormTitleLabel: UILabel { override var font: UIFont! { get { return UIFont.systemFont(ofSize: 36, weight: .heavy) } set { super.font = font } } }
这段代码有两个关键问题导致文本截断:
- Setter逻辑错误:你在
set方法里写了super.font = font,这里的font不是传入的新值newValue,而是会调用你重写的get方法返回的字体。更关键的是,你从来没有主动触发过这个setter,导致父类UILabel内部存储的font属性还是默认的小字体。 - 布局计算不匹配:
UILabel的文本尺寸计算完全依赖父类内部存储的字体值,但你显示时用的是get方法返回的36号粗体大字体——相当于用小字体的预留空间去装大字体的文本,自然就会出现截断。
修复代码为什么有效
@IBDesignable class FormTitleLabel: UILabel { override var font: UIFont! { get { return UIFont.systemFont(ofSize: 36, weight: .heavy) } set { super.font = font } } override init(frame: CGRect) { super.init(frame: frame) setup() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! setup() } override func awakeFromNib() { super.awakeFromNib() setup() } private func setup() { self.font = UIFont.systemFont(ofSize: 36) } }
你的修复做了最核心的一件事:在控件初始化的全流程里主动触发了字体设置:
- 通过
init(frame:)(代码初始化)、init(coder:)(IB初始化)和awakeFromNib(从xib/storyboard加载)这三个核心入口,调用setup方法给self.font赋值。 - 这会触发你重写的
set方法,把get方法返回的36号粗体字体传给父类的font属性,让父类内部存储的字体和你显示用的字体保持一致。 - 这样
UILabel在计算文本布局时,用的就是正确的大字体尺寸,文本就能完整显示,不会再被截断。
另外提个小优化:其实可以把setter改成super.font = newValue,逻辑会更清晰,也能避免潜在的递归风险,比如:
override var font: UIFont! { get { return UIFont.systemFont(ofSize: 36, weight: .heavy) } set { super.font = newValue } }
不过你的修复方案已经通过主动初始化赋值解决了核心问题,所以能正常工作。
内容的提问来源于stack exchange,提问作者Hapeki
相关产品推荐
相关产品推荐

