Swift / iOS 16 空的 SwiftUI 列表背景颜色

6

我的应用程序是使用SwiftUI构建的,在iOS 16上基本运行良好,除了我目前正在修复的一些设计怪癖。

其中一个怪癖是列表的背景颜色。以前,我使用Introspect来设置列表背景的颜色,但由于列表在iOS 16中已被重新实现,这种方法不再起作用。

我已经通过使用新的scrollContentBackground修饰符来解决了iOS 16设备上的这个问题:

List() {
   some foreach logic here
}
.background(color)
.scrollContentBackground(.hidden)

这个功能基本正常,除了一个问题。

当列表为空时,背景色被忽略了,它显示为白色或黑色背景(甚至不是分组的背景颜色),这取决于浅色模式或深色模式的设置。

有没有其他人遇到过这个问题(或者是我做错了什么?),如果有,你们都想出了什么解决方案?

谢谢, C

4个回答

7

以下是我完成的内容

if data.count > 0 {
    List()
} else {
    Color.clear
}

这是最好的答案,对我起了作用。 - Dmytro Titov
这是最好的答案,对我起了作用。 - undefined

3

可能不适用于所有人,但我有一个解决自己问题的方法。

当列表为空时,我使用叠加层来呈现消息,所以我决定在这里使用老的ZStack技巧,它似乎按预期工作。

示例:

List() {
    ForEach(data, id: \.id) { item in
      // some foreach logic here
    }
}
.background(Color.red)
.scrollContentBackground(.hidden)
.overlay(Group {
    if(data.isEmpty) {
        ZStack() {
            Color.red.ignoresSafeArea()
            Text("Empty List!")
        }
    }
})

希望这能帮助其他人!

1
抱歉兄弟,这仍然无法解决我遇到的问题。 - DoubleShy0N
@DoubleShy0N,你遇到了什么问题? - Carl

3

不幸的是,为了确保列表非空,您需要向List添加一个元素。

我在查找相关问题时发现了您的问题,我发现唯一删除List中白色/黑色背景的方法是添加任何非EmptyView视图。 然而,这并不意味着它必须可见,出现在屏幕上或显示任何内容。

请尝试以下操作:

List {
  Group {
    ForEach(data, id: \.id) { item in
      // do your ForEach logic here
    }

    if data.isEmpty {
      Spacer()
    }
  }
  .listRowBackground(Color.clear)
}
.scrollContentBackground(.hidden)

如果由于某些原因 Spacer() 无法使用,请尝试以下方法:
Text("ListFix")
  .hidden()
  .accessibility(hidden: true)

相反,或者类似的东西。添加 .accessibility(hidden: true) 是很重要的,否则任何使用VoiceOver的人都会阅读这段文本。

考虑将一些有用的空状态消息添加到您的 List 中,也许可以将空状态移动到我的 List 内部,而不是将整个 List 包装在一个 if !data.isEmpty 条件中。但如果您不想要空状态,只需添加一个可以隐藏的视图即可完成工作。


我的回答展示了如何使用“overlay”修饰符来着色背景并添加状态消息,以便在列表为空时解决此问题。这是目前最干净和最简单的方法。 - Carl
然而,这并不总是解决问题的方法,因为如果List为空,iOS 16会忽略.scrollContentBackground(.hidden)并给空列表一个白色/黑色背景。确保列表中有一些内容,即使它被隐藏了,也可以让它再次正常工作。 - Rhys Morgan
这就是覆盖层的作用,它包含一个ZStack,其中有一个全屏颜色和空消息呈现在其前面。 - Carl
1
只有在列表后面有一种坚实的纯色背景并且易于复制时,这才有帮助。如果你的背景是渐变的,那么就非常困难(在不同屏幕尺寸的设备上几乎不可能)让它透过去显示出来。 在“列表”中添加任何内容都可以确保它遵守“.scrollContentBackground(.hidden)”并移除白色/黑色背景,使您的实际背景显示出来。 - Rhys Morgan
你可以只显示一个带有类似 foregroundStyle(.secondary) 的“无数据”元素,以使其与常规列表项区分开来。 - Lerk

0
我也在寻找同样的解决方案,从@Rhys Morgan的回答中得到了灵感。当列表为空时,我添加了一个带有空字符串的TextView,并使用了.listRowBackground(Color.clear),这样就解决了问题。
List {
                    ForEach(items) { item in
                        VStack(alignment: .leading) {
                            Text(item.task ?? "")
                                .font(.headline)
                                .fontWeight(.bold)
                            
                            Text("Item at \(item.timestamp!, formatter: itemFormatter)")
                                .font(.footnote)
                                .foregroundColor(.gray)
                            
                        }
                    }
                    .onDelete(perform: deleteItems)
                    if(items.isEmpty){
                        Text("")
                            .listRowBackground(Color.clear)
                    }
                }//: LIST
                .listStyle(InsetGroupedListStyle())
                .shadow(color: Color(red: 0, green: 0, blue: 0, opacity: 0.3), radius: 12)
                .padding(.vertical,0)
                .frame(maxWidth: 640)
                .background(.clear)
                .scrollContentBackground(.hidden)

在这里观看结果


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接