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

Posted

技术标签:

【中文标题】如何从嵌套的 ForEach 循环中获取连续的索引号?【英文标题】:How to get continuous index numbers from nested ForEach loop? 【发布时间】:2021-11-17 16:58:57 【问题描述】:

我正在为我的小部件扩展使用 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)
                
            
        
        
    

【问题讨论】:

这个问题已经回答了。您不应在事后对其进行编辑以提出第二个问题。 作为一个单独的问题提出,谢谢。 【参考方案1】:

使用LazyVGrid

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

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

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

使用它会为你解决这个问题。

没有LazyVGrid

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

index = row*numberOfCols + column

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

【讨论】:

感谢您的回答!我使用了 LazyVGrid,它按预期工作。唯一的问题是现在不会自动设置网格大小。默认的 VStack + HStack 单元大小很棒,我需要设置它们,但除此之外一切都很好! @OğuzhanVarsak 太棒了!您应该能够使用为列定义的GridItems 配置列的大小。您可以在此处阅读有关 GridItem 的更多信息...developer.apple.com/documentation/swiftui/griditem 您好!我在使用 LazyVGrid 时遇到了一些问题。我的 LazyVGrid 单元将顶视图(与 LazyVGrid 在同一个 VStack 中)推出框架。有解决方法吗?我找不到如何将视图的顶部锚定到框架上。 @OğuzhanVarsak 嗯...没有看到代码我不确定为什么会这样。您能否在 *** 上添加一个新问题以显示您的代码,然后将其链接到此处。我会看看。谢谢 如果可以的话我就更新一下这里的代码?已经没有太多变化了。

以上是关于如何从嵌套的 ForEach 循环中获取连续的索引号?的主要内容,如果未能解决你的问题,请参考以下文章

从foreach循环中获取当前索引[重复]

如何在 ForEach 循环中获取计数变量

我如何在每个循环中获取索引,并且如何执行1个以上的操作?

如何在 smarty 中找到 foreach 循环的最后一个索引

如何在 C# foreach 中获取索引

如何在刀片foreach循环中获取迭代次数