1. 程式人生 > >iOS UITextField 的坑:更改顏色導致字型忽大忽小

iOS UITextField 的坑:更改顏色導致字型忽大忽小

每年開始的時候都許願,今年要好好寫部落格,記錄學到的東西,然後只堅持一兩篇。今年也不例外!這就是第一篇:)

最近遇到一個非常奇怪的 UI bug。業務上有一個需求,就是在頁面滾動的時候,讓一個 UITextField 的文字顏色逐漸變化。很正常的需求吧?然而出現了非常奇怪的現象:儘管程式碼只改了字型的顏色,文字的大小卻也會忽大忽小,像下面的 gif 所示:

忽大忽小的文字

我做了一個 demo 來重現問題(demo 地址),程式碼非常簡單,如下:

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 = "這是一行測試用的文字" view.addSubview(textfield) } @IBAction func sliderValueChanged(_ sender: Any) { let
textColor = UIColor.black.colorByBlending( with: UIColor.white, percent: CGFloat(slider.value)) textfield.defaultTextAttributes = [ // 註釋掉下面這一行,問題就會消失 .font: UIFont.systemFont(ofSize: fontSize), .foregroundColor: textColor ] // textfield.font = UIFont.systemFont(ofSize: fontSize) } } 複製程式碼

可以看到,設定 defaultTextAttributes 的時候,只有 .foregroundColor 這個屬性發生了變化,而雖然有 .font 這個 key 但 value 帶的 fontSize 是一個常數,它是完全沒變化的。然鵝,卻出現了字型忽大忽小的問題……

經過一番研究,發現這個 bug 有兩個必要的重現條件:

  1. 文字必須是中文。其他語言我沒試過,純英文的文字是不會出現問題的;
  2. defaultTextAttributes 必須得有 .font 這個 key。如果沒有這個 key,也是不會出現問題的。

這肯定是蘋果 UIKit 自帶的 bug 無疑了。既然知道了重現條件,解決這個問題的方法也很簡單…… 就是在設定 defaultTextAttributes 的時候,先把 .font 從裡面去掉,然後在後面再補一句 textfield.font = UIFont.systemFont(ofSize: fontSize) 就行了。

因為工程上程式碼比較複雜,我花了好久才定位到問題、做出能重現的 demo…… 所以在此記錄一下,祭奠我浪費的幾個小時本可以睡懶覺的時間 ><