【问题标题】:Strange spaces between ForEach views SwiftUIForEach 视图 SwiftUI 之间的奇怪空间
【发布时间】:2021-08-07 18:16:35
【问题描述】:

我有这样的代码:

ForEach(listItems, id: \.self){ item in
                HStack{
                    Button(action: {
                        actionSheet()
                    }) {
                        HStack(spacing: 10) {
                            Image(item.img)
                            Text(item.title)
                                .modifier(TextHandler(fontSize: 16, rgbArray: [47,47,47]))
                                .padding(.leading,10)
                        }
                    }.padding(.all,20)
                    
                    Spacer()
                }
                .background(Color(red: listItemBack, green: listItemBack, blue: listItemBack))
                .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
            }

结果是:

为什么这个循环中的视图会有这个奇怪的空白。但是当我只将带有一些项目数据的文本放入这个循环时,这些空格就消失了。为什么会这样?也许我的填充物在某处重叠?我尝试使用此代码:

.listRowInsets(EdgeInsets())

但它对我一点帮助都没有。

【问题讨论】:

  • 您指的是哪个空白?在视图之间还是在底部?此外,它有助于提供Minimal, Reproducible Example
  • 此列表的视图之间,底部空白处与截图错误切割相连)

标签: swift swiftui


【解决方案1】:

这是您在Button 上的填充,您在(.all,20) 拥有它。

ForEach(listItems, id: \.self){ item in
                HStack{
                    Button(action: {
                        actionSheet()
                    }) {
                        HStack(spacing: 10) {
                            Image(item.img)
                            Text(item.title)
                                .modifier(TextHandler(fontSize: 16, rgbArray: [47,47,47]))
                                .padding(.leading,10)
                        }
                    }.padding(.all,20)                         
                    Spacer()
                }
                .background(Color(red: listItemBack, green: listItemBack, blue: listItemBack)). // This is causing the spacing. It needs to be moved to the parent view.

                .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
            }

如果您希望它们在没有空白的纯色背景中间隔开,则背景需要放在父视图上。当我将您的代码放入VStack 并将.background 放在VStack 上时,我想出了这个:

这是你要找的吗?

编辑:您将Button 上的填充一直设置为20。这将在每个创建的按钮周围留出空间。然后将.background 放在每个包含ButtonHStack 上。 .padding 在按钮周围,但HStack 只是Button 的高度,而不是Button.padding 的高度。如果您将.padding(.all,20) 注释掉,您将看到视图折叠,直到Buttons 彼此相邻。我确定你不希望这样。

通过将背景放在父视图上(在我的情况下,我将您的代码放入 VStack,所以 .background 去了那里),您在所有按钮后面放置一个背景,而不是每个按钮一个背景有间隙。

第二次编辑: 这是我最小的、可重现的示例代码。请注意,我无权访问您的 listItemBack 变量来设置背景颜色,所以我只使用了灰色。

import SwiftUI

struct SpaceView: View {
    
    @State var listItems: [ListItem] = [ListItem(title: "First", img: "internaldrive"),
                                        ListItem(title: "Second", img: "paperplane"),
                                        ListItem(title: "Third", img: "scribble"),
                                        ListItem(title: "Fourth", img: "tram.fill"),
                                        ListItem(title: "Fifth", img: "clock"),
                                        ListItem(title: "Sixth", img: "a.magnify"),
                                        ListItem(title: "Seventh", img: "arrowshape.zigzag.forward")
    ]
    
    var body: some View {
        VStack {
        ForEach(listItems){ item in
                        HStack{
                            Button(action: {
                                print("\(item.title) Pressed")
                            }) {
                                HStack(spacing: 10) {
                                    Image(systemName: item.img)
                                    Text(item.title)
//                                        .modifier(TextHandler(fontSize: 16, rgbArray: [47,47,47]))
                                        .padding(.leading,10)
                                }
                            }.padding(.all,20)
                            
                            Spacer()
                        }
//                        .background(Color(red: listItemBack, green: listItemBack, blue: listItemBack))
                          //.background(Color.gray) // Uncomment here and comment out the other background to see the difference.

                        .padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
                    }
    }
        .background(Color.gray) // Comment out here to switch between your view an my view.
    }
}

struct ListItem: Identifiable, Hashable {
    var id = UUID()
    var title: String
    var img: String
}

struct SpaceView_Previews: PreviewProvider {
    static var previews: some View {
        SpaceView()
    }
}

【讨论】:

  • 是的,你的截图是我想看到的,但是当我尝试将我的子视图放入 VStack 时,最终结果没有完整的 scr 宽度,你能添加这个截图的代码吗为了更好地理解?
  • 你能添加更多关于你的代码的信息吗?
  • 正如我之前所说,您的解决方案看起来像我想要做的,但我仍然没有看到任何与您的屏幕截图相关的解决方案:(
  • 这就是为什么你应该离开发布一个最小的、可重现的例子。如果你发布一个代码片段,你会得到一个代码片段。