ObjecTips

Swift & Objective-C で iOS とか macOS とか

アプリ全体を Dynamic Type に対応させる

アプリを Dynamic Type に対応させようと思って実装してみた。

IBでフォント指定可能なUI

まずIB上で設置できるUIをいくつか配置する。
UILabel UIButton UITextField UITextView はIB上でフォントの設定ができるので Dynamic Type に対応したフォントを設定する。

通常のテキストサイズの時は以下の様になる。

f:id:Koze:20150603095029p:plain

次に設定.app の 画面表示と明るさ > 文字サイズを変更
もしくは 一般 > アクセシビリティ > より大きな文字 で文字サイズを変更する。
シミュレータの場合は 一般 >アクセシビリティ > Larger Text から設定できる。
文字サイズを変更すると以下の様になる。

f:id:Koze:20150603100007p:plain

IBでフォント指定ができないUI

UINavigationBar UIBarButtonItem UITabBarItem UISearchBar UISegmentedControl はIB上でフォントサイズを設定できないのでもしかしたら自動でフォントサイズを調整してくれるのかと思ったがそうではないらしい。
これらのクラスについては UIFontpreferredFontForTextStyle: メソッドで作成したフォントを自分で各UIに設定する必要がある。
各UIのクラスに一律にフォントを設定するには UIAppearance プロトコルが使える。
以下の様なコードで実装できる。

結果は以下

f:id:Koze:20150603100017p:plain

設定されたフォントサイズによって各UIのサイズを変えるなどした方がベターに思えるが、アピアランスを使う事でひとまずの Dynamic Type 対応はできた。

UIPickerView と UIDatePickerView

UIPickerViewUIDatePicker クラスについては UIAppearance に対応しておらずアピアランスではカスタマイズする事が出来ない。
UIPickerView は表示を好きにカスタマイズできる仕組みが用意されているが UIDatePicker の方はそういったAPIが無くカスタマイズが出来ないので、UIDatePicker を好きにカスタマイズするのであれば Private API を使うか UIPickerView のサブクラスで自前の DatePicker クラスを作成する必要がある。

UIAlertController
    // UIAlertControllerStyleAlert or UIAlertControllerStyleActionSheet
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title"
                                                                             message:@"Message"
                                                                      preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"キャンセル" style:UIAlertActionStyleCancel handler:nil]];
    [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
    [self showViewController:alertController sender:nil];

UIAlertController クラスによるアラート表示とアクションシート表示は特にコードを書かずとも自動で Dynamic Type に対応している。

f:id:Koze:20150603201019p:plain f:id:Koze:20150603201026p:plain


後から気付いたけどAppleの標準アプリ、例えば時計アプリやPodcastアプリを見てみると NavigationBar と TabBar は Dynamic Type に対応させていない。
計算機アプリにいたっては元のパーツのサイズが大きいためか Dynamic Type 自体に対応していない。
アプリの性質やコンテンツを考慮してどこまで Dynamic Type に対応すべきかを一考した方が良いのかも知れない。