如何从嵌套的 ForEach 循环中获取连续的索引号?

How to get continuous index numbers from nested ForEach loop?

我正在为我的小部件扩展使用 4 块网格。

我想用一组元素填充这些网格。

let exampleArray = ["test1","test2","test3","test4"]

当我使用两个嵌套的 ForEach 循环时,我无法获取第 4 个索引中的元素。

VStack {
    ForEach((0..<2)) { column in
        HStack {
            ForEach((0..<2)) { index in
                ZStack (alignment: .bottomLeading) {
                    Text(newsList[(index+column)])  // 0+0, 1+0, 0+1, 1+1
                    // Text = test1, test2, test2, test3
                }
            }
        }
    }
}

有什么办法可以解决这个问题吗?因为它在View,我无法使用任何操作

视图的完整代码:

struct AppWidgetEntryView : View {
    var entry: Provider.Entry
    
    @Environment(\.widgetFamily)
    var widgetFamily

    var body: some View {
        VStack(alignment: .trailing, spacing: 6) {
            Image("logo")
                .frame(maxWidth: .infinity, alignment: .leading)

            if widgetFamily == .systemLarge {
                VStack {
                ForEach((0..<2)) { column in
                    HStack {
                        ForEach((0..<2)) { index in
                            ZStack (alignment: .bottomLeading) {
                                if let url = URL(string: imageList[(index+column)]), let imageData = try? Data(contentsOf: url),
                                let uiImage = UIImage(data: imageData) {

                                Image(uiImage: uiImage)
                                    .centerCropped()
                                    .frame(maxHeight: 150, alignment: .center)
                                    .cornerRadius(10)
                                            .overlay(RoundedRectangle(cornerRadius: 10)
                                            .stroke(Color.gray, lineWidth: 1))
                                            .shadow(radius: 10)
                                } else {
                                    Image("ph_background")
                                        .centerCropped()
                                        .frame(maxHeight: 150, alignment: .center)
                                        .cornerRadius(10)
                                                .overlay(RoundedRectangle(cornerRadius: 10)
                                                .stroke(Color.gray, lineWidth: 1))
                                                .shadow(radius: 10)
                                }
                                
                                Text(newsList[(index+column)])
                                    .font(.system(size: 12))
                                    .foregroundColor(.white)
                                    .fontWeight(.light)
                                    // .frame(maxHeight: 50)
                                    .background(Rectangle().fill(Color.black).blur(radius: 20))
                                    .padding(.bottom, 5)
                                    .padding(.leading, 5)
                                    .padding(.trailing, 5)
                                    .padding(.top, 5)
                            }
                        }
                    }
                }
            }
        }
    }
}

解决方案 请检查已接受的答案。

struct AppWidgetEntryView : View {
    var entry: Provider.Entry
    
    @Environment(\.widgetFamily)
    var widgetFamily

    var body: some View {
        var columns: [GridItem] =
                 Array(repeating: .init(.fixed(100)), count: 2)

        if widgetFamily == .systemLarge {
        LazyVGrid(columns: columns) {
            ForEach((0..<4)) { index in
                ZStack (alignment: .bottomLeading) {
                    if let url = URL(string: imageList[(index)]), let imageData = try? Data(contentsOf: url),
                    let uiImage = UIImage(data: imageData) {

                    Image(uiImage: uiImage)
                        .centerCropped()
                        .frame(maxHeight: 150, alignment: .center)
                        .cornerRadius(10)
                                .overlay(RoundedRectangle(cornerRadius: 10)
                                .stroke(Color.gray, lineWidth: 1))
                                .shadow(radius: 10)
                    } else {
                        Image("ph_background")
                            .centerCropped()
                            .frame(maxHeight: 150, alignment: .center)
                            .cornerRadius(10)
                                    .overlay(RoundedRectangle(cornerRadius: 10)
                                    .stroke(Color.gray, lineWidth: 1))
                                    .shadow(radius: 10)
                    }
                    
                    Text(newsList[(index)])
                        .font(.system(size: 12))
                        .foregroundColor(.white)
                        .fontWeight(.light)
                        // .frame(maxHeight: 50)
                        .background(Rectangle().fill(Color.black).blur(radius: 20))
                        .padding(.bottom, 5)
                        .padding(.leading, 5)
                        .padding(.trailing, 5)
                        .padding(.top, 5)
                }
            }
        }
        }
    }
}

使用LazyVGrid

我觉得你真的应该为此使用 LazyVGrid...

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

它的工作方式与 List 类似,但它将每个项目都放在一个列网格中。

使用它可以为您解决这个问题。

没有LazyVGrid

如果您真的不想使用 LazyVGrid(尽管请使用它)。那么您使用的计算不正确。计算类似于...

index = row*numberOfCols + column

您不能只使用该行,因为这只会使每行的索引增加 1。但是您需要将索引增加每行的列数(在您的情况下为 2)。