如何获取动态 List/ForEach 可绑定元素的索引(新的 Xcode 13 语法)? [英] How to get the index of a dynamic List / ForEach bindable element (new Xcode 13's syntax)?

查看:17
本文介绍了如何获取动态 List/ForEach 可绑定元素的索引(新的 Xcode 13 语法)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,要在动态集合中的元素和 List 的行之间设置绑定,我们必须这样做:

Until now, to setup bindings between the elements in a dynamic collection and the rows of a List we had to do like that :

List(Array(zip(data.indices, data)), id: \.1.id) { index, _ in
    HStack {
        Text((index + 1).description)
        TextField("", text: Binding(
            get: { data[index].text },
            set: { data[index].text = $0 }
        ))
    }
}

我们需要:绑定元素的索引;+ List 的元素标识符(以避免奇怪的动画);和自定义 Binding 以避免在删除最后一行时崩溃.

We need : the index of the element for the binding ; + the element identifier for the List (to avoid weird animations) ; and a custom Binding to avoid a crash when deleting the last row.

这很复杂(我不确定它是否非常有效).从 WWDC21 开始,我们有了新的语法(可以向后部署):

It's complicated (and I'm not sure it's very efficient). Since WWDC21, we have a new syntax (which can be back-deployed):

List($data) { $item in
    HStack {
        Text("Index ?")
        TextField("", text: $item.text)
    }
}

更干净.

虽然强烈建议使用这种新语法,但如果能够访问闭包中元素的索引,那就太好了.你知道我们怎么做吗?

But while it is strongly recommended to use this new syntax, it would be nice to be able to access the element's index in the closure. Do you know how we can do it?

我试过了(它有效),但我觉得这不是正确的方法:

I tried this (it works), but I feel like it's not the right way to do it :

let d = Binding(get: {
    Array(data.enumerated())
}, set: {
    data = $0.map {$0.1}
})
List(d, id: \.1.id) { $item in
    HStack {
        Text("\(item.0 + 1)")
        TextField("", text: $item.1.text)
    }
}

推荐答案

您可以自己构建包装器:

You can build wrapper by yourself:

struct ListIndexed<Content: View>: View {
    let list: List<Never, Content>
    
    init<Data: MutableCollection&RandomAccessCollection, RowContent: View>(
        _ data: Binding<Data>,
        @ViewBuilder rowContent: @escaping (Data.Index, Binding<Data.Element>) -> RowContent
    ) where Content == ForEach<[(Data.Index, Data.Element)], Data.Element.ID, RowContent>,
    Data.Element : Identifiable,
    Data.Index : Hashable
    {
        list = List {
            ForEach(
                Array(zip(data.wrappedValue.indices, data.wrappedValue)),
                id: \.1.id
            ) { i, _ in
                rowContent(i, Binding(get: { data.wrappedValue[i] }, set: { data.wrappedValue[i] = $0 }))
            }
        }
    }
    
    var body: some View {
        list
    }
}

用法:

ListIndexed($items) { i, $item in
    HStack {
        Text("Index \(i)")
        TextField("", text: $item.text)
    }
}

这篇关于如何获取动态 List/ForEach 可绑定元素的索引(新的 Xcode 13 语法)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆