UIKitのアップデート #WWDC22
What's new in UIKitとその周辺情報を調べた結果をまとめておきます。
※すべて公開情報を元に書いています。
ナビゲーションバー
browserとeditorという2つの新しいナビゲーションスタイルが導入された。

browserは履歴やフォルダ構造を使用するアプリに適している。editorはドキュメントの編集がメインのアプリに適している。
iOS 16ではボタン要素をバーの中央に置くことができる。これによってユーザは多くのオプションが見られる。ドラッグアンドドロップでツールバーのカスタマイズもできる。

窮屈なときは自動でアイテムが収納される。

タイトルにもメニューアイテムを追加することができる。

関連リンク:
検索と置換
UITextView、WKWebView、PDFViewなどはisFindInteractionEnabledフラグを設定するだけで検索/置換機能を使うことができる。

UIFindInteractionを使うと検索/置換文字列を入力するためのパネルが表示される。上述以外のviewでも、自分で一定の実装をすることで検索/置換機能を使うことができる(下記ドキュメント参照)。
関連リンク:
編集メニュー
編集時のメニューがよりインタラクティブになる。アクションを表示するメニューのプレゼンテーションスタイルは、インタラクションの入力方法に従う。タッチインタラクションの場合は編集メニューで表示される。ポインタベースの入力を持つデバイスで、セカンダリクリックに反応する場合はコンテキストメニューで表示される。


UITextView、UITextFieldなどの標準的なUIKitクラスは、編集メニューインタラクションが使えるようあらかじめ設定されている。一般的なviewで使いたい場合は下記リンク先のようなコードを書けば良い。
UIMenuControllerはiOS 16でdeprecatedになり、代わりにUIEditMenuInteractionを使うことが推奨されている。
関連リンク:
サイドバー
追加コードなしでサイドバーを取り入れることができる。

カレンダー
新しくUICalendarViewが登場した。

以下のような機能が備わっている。
- 単一、もしくは複数の日付を選択
-
selectionBehaviorで単一選択か複数選択を決定できる。複数の場合はUICalendarSelectionMultiDateDelegateで、単一の場合はUICalendarSelectionSingleDateDelegateでハンドリングする。
-
- 選択可能な日付範囲の制限
-
availableDateRangeを使って設定する
-
- 特定の日付を選択から除外
-
dateSelection:canSelectDate:メソッドでfalseを返す
-
- 特定の日付に装飾
-
UICalendarViewDelegateのcalendarView(_:decorationFor:)を実装し、UICalendarView.Decorationを使って様々な装飾を加えることができる。
-


使用したいカレンダーは明示しておく必要があることに注意する(Calendar(identifier: .gregorian)の部分)。
UICalendarViewとUIDatePickerの大きな違いは、UICalendarViewは日付をNSDateComponentsで表現していて、UIDatePickerはNSDateで表現していること。また、装飾ができるか否かの違いもある。
関連リンク:
ページコントロール
選択されているページとそうでないページで異なる画像を設定できるようになった。
ページコントロールの向きを設定できるようになった。

関連リンク:
ペースト
今まではコピペ時にトーストのようなバナーが表示されていたが、iOS 16からはペーストボードの使用許可を求めるアラートが表示されるように。

UIPasteControlを使えばアラート表示を回避することができる。

関連リンク:
カスタムサイズのシート
任意のサイズのシートが作成できるようになった。この機能を利用するには.customdetentを使用して、高さかパーセンテージを指定する。


.customdetentに識別子を与えて管理することもできる。

customブロックから返される値は、フローティングシート(iPadなど)とエッジアタッチシート(iPhoneなど)の両方で同じ計算が機能するようにするため、下部のSafeAreaは考慮されていない。
関連リンク:
SF Symbols
monochrome, multicolor, hierarchical, paletteの4つのレンダリングモードをサポート。iOS 15まではmonochromeがデフォルトだったが、iOS 16からはhierarchicalがデフォルトになる。 UIImage.SymbolConfiguration.preferringMonochrome() を使えばモノクロレンダリングできる。

シンボルによっては0〜1の値でバリエーションを表現できるようになった。speaker.3.wave.fillの例は以下の通り。

今までのSF Symbols APIで取得したUIImageにvariableValueパラメータを追加すれば使うことができる。

関連リンク:
UIScreen
UIScreen.mainがdeprecatedに。UITraitCollection、UISceneAPIなどの具体的なAPIを使うようにする。
関連リンク:
セルのセルフリサイジング
iOS 16では表示されているセル内のコンテンツが更新されると、そのコンテンツに合わせてセルが自動的にリサイズされる。UIListContentConfigurationを使っている場合はselfSizingInvalidationはデフォルトで有効になっている。

UIListContentConfigurationを使ってセルを構成している以外のケースでは、セルまたはcontentViewに対してinvalidateIntrinsicContentSizeメソッドを呼び出してセルのサイズを変更することができる。
デフォルトではアニメーション付きでリサイズされるが、UIView.performWithoutAnimationブロックの中でinvalidateIntrinsicContentSizeを呼び出せばアニメーションを無効にできる。
セルにAuto Layoutを使用している場合は、enabledIncludingConstraintsを使うと良い。contentView内でAuto Layoutの変更を検知すると、自動的にinvalidateIntrinsicContentSizeを呼び出して必要に応じてサイズ変更をしてくれる。
関連リンク:
- selfSizingInvalidation
- invalidateIntrinsicContentSize()
- UICollectionView.SelfSizingInvalidation.enabledIncludingConstraints
UIKitとSwiftUI
同じアプリに両方のフレームワークを組み込むことがより簡単になった。UIHostingConfigurationを使えばセルの内部でSwiftUIを書くことができる。

関連リンク:
UIDevice
UIDevice.nameはユーザが設定したデバイス名ではなく、モデル名を返すようになった。取得したい場合はentitlementを使う。
UIDevice.orientationはサポートされなくなった。代わりにpreferredInterfaceOrientationなどを使用して向きを表現する。

関連リンク:
Discussion