SwiftUI 是不是可以在 ForEach 中传递绑定范围?
Posted
技术标签:
【中文标题】SwiftUI 是不是可以在 ForEach 中传递绑定范围?【英文标题】:SwiftUI is it possible to pass range of binding in ForEach?SwiftUI 是否可以在 ForEach 中传递绑定范围? 【发布时间】:2021-03-06 12:59:33 【问题描述】:我想在 ForEach 内部的模型中传递一个数组范围。
我重新创建了一个示例:
import SwiftUI
class TheModel: ObservableObject
@Published var list: [Int] = [1,2,3,4,5,6,7,8,9,10]
struct MainView: View
@StateObject var model = TheModel()
var body: some View
VStack
ForEach (0...1, id:\.self) item in
SubView(subList: $model.list[0..<5]) <-- error if I put a range
struct SubView: View
@Binding var subList: [Int]
var body: some View
HStack
ForEach (subList, id:\.self) item in
Text("\(item)")
struct MainView_Previews: PreviewProvider
static var previews: some View
MainView()
变通方法
我发现是传递所有列表并执行子视图内的范围。但我不想这样做,因为数组非常大:
struct MainView: View
@StateObject var model = TheModel()
var body: some View
VStack
ForEach (0...1, id:\.self) i in
SubView(subList: $model.list, number: i, dimension: 5)
struct SubView: View
@Binding var subList: [Int]
var number: Int
var dimension: Int
var body: some View
HStack
ForEach (subList[number*dimension..<dimension*(number+1)].indices, id:\.self) idx in
Button(action:
subList[idx] += 1
print(subList)
, label:
Text("num: \(subList[idx])")
)
【问题讨论】:
为什么SubView.subList
是一个绑定? SubView
可以以某种方式更改给它的数组,并且您希望更改反映在 TheModel.list
中吗?
@Sweeper 是的,在解决方法中,我插入了一个按钮,例如更改项目的示例
哦,对了。我没有过多阅读您的解决方法代码,并认为它们是相同的,哈哈
请注意,您不能通过从list[0..<5]
获得的ArraySlice
改变原始数组,即使没有这些 SwiftUI 的东西。所以我的想法是编写你自己的引用类型来包装一个数组,你可以将它传递给子视图,而这次不需要复制整个数组。
@Sweeper 你能用代码写出你的想法吗? :)
【参考方案1】:
我会将模型传递给子视图,因为它是一个类,将通过引用传递,然后将范围作为单独的参数传递。
这是我对 SubView 的新实现
struct SubView: View
var model: TheModel
var range: Range<Int>
var body: some View
HStack
ForEach (model.list[range].indices, id:\.self) idx in
HStack
Button(action:
model.list[idx] += 1
print(model.list)
, label:
Text("num: \(model.list[idx])")
)
请注意,我在ForEach
标头中添加了indices
,以确保我们使用索引而不是数组中的值访问数组。
调用视图看起来像
var body: some View
VStack
SubView(model: model, range: (0..<5))
Text("\(model.list.map(String.init).joined(separator: "-"))")
额外的Text
仅用于测试目的
【讨论】:
所以没办法只传递数组的一部分? 你可以,但是你必须有代码来更新模型中的数组进行更改,我看不出这会更简单以上是关于SwiftUI 是不是可以在 ForEach 中传递绑定范围?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI 的 List/ForEach 视图中是不是可以有一个 Button(action: -)
ForEach 通过多个 TextField 来验证 SwiftUI 中是不是为空