Closed5

Swift UIのForEachって何なの

mtkw0127mtkw0127
struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : Hashable

ForEachは構造体。
Data, ID, ContentというGenericを持つ。
DataはRandomAccessCollectionのサブクラス。
IDはHashableのサブクラス。

RandomAccessCollectionはCollectionの要素にランダムアクセスできることを保証するプロトコル。
Hashableはその型の値を元にHash値の計算が可能であることを保証するプロトコル。

mtkw0127mtkw0127
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension ForEach where ID == Data.Element.ID, Content : View, Data.Element : Identifiable {
    public init(_ data: Data, @ViewBuilder content: @escaping (Data.Element) -> Content)
}

ForEachから上のようなExtensionが生えていたので見てみる。

ForEach(items) { item ->
    Text(item.name)
}

上記にinitializerは上みたいなコードのためのinitializer。
第一引数:引数ラベルなしでData型を渡す。(RandomAccessCollection準拠ならなんでもOK)
第二引数:Viewを作るclouserを渡す。clouserの引数はData.ElementでContentを返す。ContentはView準拠。

@escapingって何?
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/#Escaping-Closures

ChatGpt

Swift の @escaping 属性は、クロージャ(closure)が非同期で使用されることを示すために用いられる属性です。特に、クロージャが関数やメソッドから抜けた後も、後から呼び出される可能性がある場合に使います。@escaping を使用することで、クロージャがそのスコープを越えても有効であることをコンパイラに伝えます。

clouserの実行がそのclouserを引数に渡した関数の実行後も動かしたい場合に付けるattibute。

mtkw0127mtkw0127
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension ForEach : DynamicViewContent where Content : View {
}

ForEach構造体はDynamicViewContentをiOS13から準拠している。

https://developer.apple.com/documentation/swiftui/dynamicviewcontent

DynamicViewContentというのはCollectionから生成されたViewだということ。
追加・削除等のメソッドが生えている。

ForEach(items) { item in
    NavigationLink(
        destination: {
            Text("Item at \(item.timestamp!, formatter: itemFormatter)")
        },
        label: {
            Text(item.timestamp!, formatter: itemFormatter)
        }
    )
}
.onDelete(perform: deleteItems)

onDeleteを読んでいるおかげてスワイプで削除することが可能となっている。

このスクラップは2024/08/17にクローズされました