每年開(kāi)始的時(shí)候都許愿紊服,今年要好好寫(xiě)博客檀轨,記錄學(xué)到的東西,然后只堅(jiān)持一兩篇围苫。今年也不例外!這就是第一篇:)
最近遇到一個(gè)非常奇怪的 UI bug撤师。業(yè)務(wù)上有一個(gè)需求剂府,就是在頁(yè)面滾動(dòng)的時(shí)候,讓一個(gè) UITextField
的文字顏色逐漸變化剃盾。很正常的需求吧腺占?然而出現(xiàn)了非常奇怪的現(xiàn)象:盡管代碼只改了字體的顏色,文字的大小卻也會(huì)忽大忽小痒谴,像下面的 gif 所示:
我做了一個(gè) demo 來(lái)重現(xiàn)問(wèn)題(demo 地址)衰伯,代碼非常簡(jiǎn)單,如下:
let fontSize: CGFloat = 14.0
class ViewController: UIViewController {
var textfield: UITextField!
@IBOutlet weak var slider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
textfield = UITextField(frame: CGRect(x: 52, y: 200, width: 260, height: 19))
textfield.font = UIFont.systemFont(ofSize: fontSize)
textfield.backgroundColor = UIColor.red
textfield.text = "這是一行測(cè)試用的文字"
view.addSubview(textfield)
}
@IBAction func sliderValueChanged(_ sender: Any) {
let textColor = UIColor.black.colorByBlending(
with: UIColor.white,
percent: CGFloat(slider.value))
textfield.defaultTextAttributes = [
// 注釋掉下面這一行积蔚,問(wèn)題就會(huì)消失
.font: UIFont.systemFont(ofSize: fontSize),
.foregroundColor: textColor
]
// textfield.font = UIFont.systemFont(ofSize: fontSize)
}
}
可以看到意鲸,設(shè)置 defaultTextAttributes
的時(shí)候,只有 .foregroundColor
這個(gè)屬性發(fā)生了變化尽爆,而雖然有 .font
這個(gè) key 但 value 帶的 fontSize
是一個(gè)常數(shù)怎顾,它是完全沒(méi)變化的。然鵝漱贱,卻出現(xiàn)了字體忽大忽小的問(wèn)題……
經(jīng)過(guò)一番研究槐雾,發(fā)現(xiàn)這個(gè) bug 有兩個(gè)必要的重現(xiàn)條件:
- 文字必須是中文。其他語(yǔ)言我沒(méi)試過(guò)幅狮,純英文的文字是不會(huì)出現(xiàn)問(wèn)題的募强;
-
defaultTextAttributes
必須得有.font
這個(gè) key。如果沒(méi)有這個(gè) key崇摄,也是不會(huì)出現(xiàn)問(wèn)題的擎值。
這肯定是蘋(píng)果 UIKit 自帶的 bug 無(wú)疑了。既然知道了重現(xiàn)條件逐抑,解決這個(gè)問(wèn)題的方法也很簡(jiǎn)單…… 就是在設(shè)置 defaultTextAttributes
的時(shí)候幅恋,先把 .font
從里面去掉,然后在后面再補(bǔ)一句 textfield.font = ...
就行了泵肄。
因?yàn)楣こ躺洗a比較復(fù)雜捆交,我花了好久才定位到問(wèn)題、做出能重現(xiàn)的 demo…… 所以在此記錄一下腐巢,祭奠我浪費(fèi)的幾個(gè)小時(shí)本可以睡懶覺(jué)的時(shí)間 ><