LoginSignup
18
5

More than 1 year has passed since last update.

OSのバージョン制限があるモディファイアを便利に使う方法(SwiftUI)

Posted at

はじめに

本記事は SwiftUI Advent Calendar 2022 その2 の1日目の記事です。

例えば scrollDismissesKeyboard(_:) がiOS 16.0から使えるように、OSのバージョン制限があるモディファイアを便利に使う方法を紹介します。

環境

  • OS:macOS Ventura 13.0.1
  • Xcode:14.2 (14C18)
  • Swift:5.7.2

課題

iOS 16.0未満をサポートしている場合、iOS 16.0+のモディファイアはそのままでは使えません。

SakatsuInputScreen.swift
struct SakatsuInputScreen: View {
  var body: some View {
    SakatsuInputView()
      .scrollDismissesKeyboard(.interactively) // FIXME: ビルドエラー
  }
}

モディファイアはメソッドチェーンで記述するので、間にif文を差し込めません。

SakatsuInputScreen.swift
struct SakatsuInputScreen: View {
  var body: some View {
    SakatsuInputView()
+   if #available(iOS 16.0, *) {  // FIXME: ビルドエラー
      .scrollDismissesKeyboard(.interactively)
+   }
  }
}

解決策

Viewにエクステンションで、Viewを返すメソッドを新たに定義します。

メソッド名はサフィックスに IfAvailable を付けています。

if #available() で分岐し、elseでは self をそのまま返します。
if文により返すViewの型が確定しないので、 @ViewBuilder が必要です。

SakatsuInputScreen.swift
struct SakatsuInputScreen: View {
  var body: some View {
    SakatsuInputView()
-       .scrollDismissesKeyboard(.interactively)
+       .scrollDismissesKeyboardInteractivelyIfAvailable() // !!!: ビルド成功
  }
}

+ private extension View {
+   @ViewBuilder
+   func scrollDismissesKeyboardInteractivelyIfAvailable() -> some View {
+     if #available(iOS 16.0, *) {
+       scrollDismissesKeyboard(.interactively)
+     } else {
+       self
+     }
+   }
+ }

おわりに

シンプルなtipsですが、地味に便利です。
みなさんの解決策も知りたいので、コメントなど頂けると嬉しいです :relaxed:

以上 SwiftUI Advent Calendar 2022 その2 の1日目の記事でした。
明日は埋まっていません。

18
5
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
5