😺

UIButtonのタイトルをsetTitleメソッドで変更した際にテキストのサイズが変更されないことへの対処

2022/06/12に公開

といって、こうしたらうまくいったというに過ぎません。多分、レイアウト関係のメソッドでオーバーライドした上で行わなければならないとかありそうです。現状、原因が探れたわけではないです。

問題

タイトルラベル変更前

このような状態のViewにおいて、数字で3と書かれているUIButtonのタイトルラベルを変更したいとします。その場合、UIKitではsetTitleメソッドが用意されているのですが、実行してみると意図した通りの表示にはなりませんでした。

タイトルラベル変更後

見てわかるように、タイトルラベルのフォントのサイズが小さくなってしまっています。ちなみにフォントサイズを確認すると、変更前も変更後も50.00ptです。だから設定がおかしいのではなくて、おそらくレイアウトの描画のタイミングの問題なんだろうなと思います。

//print文で確認した結果
Optional(<UICTFont: 0x7f8a6890cab0> font-family: "Helvetica Neue"; font-weight: normal; font-style: normal; font-size: 50.00pt)

対処

setTitleメソッドではうまく表示の変更が行えなかったため、次のようにiOS15.0以降で導入されたconfigurationを利用して、変更の際に設定を反映させるようにしました。

func set(Level: Int) {
        let levelString = String(Level)
        currentNBackNumberButton.configurationUpdateHandler = { button in
	    //buttonのconfigurationを取り出し
            var config = button.configuration
            config?.title = levelString
            config?.attributedTitle?.font = UIFont.systemFont(ofSize: 50)
	    //buttonのconfigurationへ反映
            button.configuration = config
        }
    }

クロージャの中にまとまった処理を記述できるので、結構分かりやすく書ける気がします。

https://developer.apple.com/documentation/uikit/uibutton/configurationupdatehandler

https://developer.apple.com/documentation/uikit/uibutton/configuration?changes=_7

ありがち例

titleLabel.textプロパティを変更する

button.titleLabel?.text = "ほにゃらら"

これは一時的にうまくいったように見えますが、実際には反映されません。このtitleLabelというプロパティの定義を見るとわかるのですが、getterしか書かれていません。setterがない以上、値の代入は意味を持たなくて、常に設定された値の出力しかしてくれません。

https://developer.apple.com/documentation/uikit/uibutton/1623992-titlelabel
https://developer.apple.com/documentation/uikit/uibutton#//apple_ref/occ/instp/UIButton/titleLabel
https://aroundthedistance.hatenadiary.jp/entry/2015/09/25/184354

参考

英語ですがとても整理されていてわかりやすいです
https://sarunw.com/posts/new-way-to-style-uibutton-in-ios15/

Discussion