[SwiftUI] PhotosPickerのonChangeをiOS17以上とiOS16以下の出しわけをきれいに描きたい

[SwiftUI] PhotosPickerのonChangeをiOS17以上とiOS16以下の出しわけをきれいに描きたい

Clock Icon2024.08.15

こんにちは。きんくまです。
SwiftUI勉強中です。

ViewのonChangeがiOS17から書き方が変わったとのことで、iOS16以下と出しわけが必要になっていました。
それでPhotosPickerのonChangeをうまく書きたいと思っていろいろと調べてようやく書けましたので記録です(メチャクチャはまった)

はまったポイントとしては、ジェネリクスとか、引数にoptionalが入っているときに中でguard文を書こうとしたけどビルドエラーになるところです。

optional対策で@ViewBuilderを使いました。
guard文はやめてif文にしました。

あとViewModifierの方で書こうとしたけど、そっちはうまくいかなかったです


import SwiftUI
import PhotosUI

private extension PhotosPicker {

    @ViewBuilder
    func onChange_iOS17<T: Equatable>(item: T?, action: @escaping (T) -> Void) -> some View {
        if let item {
            if #available(iOS 17.0, *) {
                onChange(of: item, initial: true) { oldValue, newValue in
                    action(newValue)
                }
            } else {
                onChange(of: item) { newItem in
                    action(newItem)
                }
            }
        } else {
            self
        }
    }
}

struct ContentView: View {
    @State var photoPickerSelectedImage: PhotosPickerItem?

    var body: some View {
        PhotosPicker(selection: $photoPickerSelectedImage, matching: .images, preferredItemEncoding: .automatic, photoLibrary: .shared()) {
            Text("フォトライブラリーから選択")
        }
        .onChange_iOS17(item: photoPickerSelectedImage) { item in
            // ここに処理を書く
            print("選択されたよ!")
        }
    }
}

参考

【Swift】iOS16までのonChangeとiOS17からのonChangeを使い分ける

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.