SwiftUIとの連携強化や新コンポーネント追加によって、より洗練されたUIKit
このセクションではUIKitに関する内容について解説していきます。今回のアップデートで新たに追加されたUIコンポーネントの紹介や、SwiftUIとの連携が強化された部分について記載しています。
新たなコントロールの追加
UICalendarView
アプリの機能としてカレンダー表示を行いたいというケースはよくあるかと思います。これをiOS標準のインターフェースで実現しようとする場合、iOS 15まではUIDatePickerでカレンダーを表示する方法しかありませんでした。そのため、アプリ内の任意の場所にカレンダーUIを埋め込むことはできず、そういった要件を実現するにはサードパーティのライブラリを利用することが一般的だったかと思います。iOS 16では、UICalendarViewと呼ばれる新しい標準UIコンポーネントが追加されました。これによりサードパーティライブラリに依存せず、標準UIだけでこれらの要件が実現可能となります。
UICalendarViewは以下のような柔軟なカスタマイズを提供します。
- 複数日付の選択
- 単一日付の選択
- 個別の日付の無効化
- デコレーションによる注釈表示
また、日付データの管理もNSDateではなくNSDateComponentsを用いて行います。最低限の実装は以下のようになり、これだけでApple標準のカレンダーUIを表示することができます。
let calendarView = UICalendarView() calendarView.delegate = context.coordinator calendarView.calendar = Calendar(identifier: .gregorian) return calendarView
選択のインタラクションを加えるには、UICalendarViewのselectionBehaviorにUICalendarSelectionオブジェクトをセットすることで実現します。単一選択の場合はUICalendarSelectionSingleDateを、複数選択の場合はUICalendarSelectionMultiDateを用いることになります。サンプルでは複数選択での実装を用いました。
let multiDateSelection = UICalendarSelectionMultiDate(delegate: context.coordinator) multiDateSelection.selectedDates = [ calendarView.calendar.dateComponents(in: .current, from: Date()) ] calendarView.selectionBehavior = UICalendarSelectionMultiDate(delegate: context.coordinator)
このようにselectionBehaviorの実装を加えることで、「selectedDatesに予め指定した日付」+「タップによって選択された日付」の部分で円形のハイライトが施されるようになります。UICalendarSelectionMultiDateDelegateに準拠させたクラスを用意しておけば、選択イベントを拾って任意の処理を挟むことも可能なので、ここでアプリケーション特有の実装を加えることもできます。
class Coordinator: NSObject, UICalendarViewDelegate, UICalendarSelectionMultiDateDelegate { func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didSelectDate dateComponents: DateComponents) { } func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didDeselectDate dateComponents: DateComponents) { } }
日付の下に表示する注釈表示は、UICalendarViewDelegateのデリゲートメソッドで指定することができます。例えば、以下のような実装を加えると添付画像のような表示を行うことができます。
class Coordinator: NSObject, UICalendarViewDelegate, UICalendarSelectionMultiDateDelegate { func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? { switch dateComponents.day { case 1: return .image(UIImage(systemName: "sun.min.fill"), color: .orange, size: .large) case 2: return .default(color: .red) case 3: return .customView { let label = UILabel() label.text = "予定あり" label.font = .systemFont(ofSize: 12) return label } default: return nil } } }
注釈に用いたView自体に対してはインタラクションを加えることはできないので、あくまで表示用のViewとして扱うことができるという形になっています。
SwiftUIとの連携強化
UIHostingConfiguration
iOS 15以前でCollectionViewやTableViewのセルをSwiftUIで作る場合、UIHostingControllerを用いて実装を行うことが必要でした。これが、iOS 16からはUIHostingConfigurationオブジェクトを生成し、セルに受け渡すだけで簡単にUIKitの世界にSwiftUIのViewを持ち込むことが可能になります。
Viewのレイアウト処理も開発者側で手動でコントロールする必要はなく、自動で最適なレイアウトが行われるようになっています。これは新しく追加されたSelf-resizing cellsの機能を活用して実現されています。また、ObservableObjectをCell内のSwiftUIViewに受け渡すことで、データとViewを直接的に繋ぎこみ、データの変更を自動でUIに反映させることも可能となっています。
UIKitについてのまとめ
以上がUIKitのアップデート内容のご紹介でした。iOSアプリを開発する場合、SwiftUIによる開発を選択するケースが昨今増えてきていますが、UIKitも継続的に進化しています。長い間ユーザーに愛されているアプリなどは今後もUIKitでの開発は続いていくと思うので、これらの新機能を活用することでより効率的にアプリ開発を進められそうです。
おわりに
今回の記事では、WWDC2022で発表されたChartsフレームワークとUIKit関連のアップデートについてをご紹介しました。UIKitに関しても着実に進化を遂げていますが、その進化の方向もSwiftUIを主導としてきているような印象を受けました。これらのことから、Appleデバイスで動作するアプリの開発は、今後もよりSwiftUIを活用したものになっていきそうです。次回のWWDCにて驚くような発表があることを楽しみにしつつ、UIの最新機能を使いこなして楽しく開発を行っていきましょう。