Reputation: 618
My app is built in SwiftUI and mostly works as is with iOS 16 apart from a couple of design quirks which I'm currently working on a fix for.
One of the quirks is the background colours of lists. Previously I have used Introspect to set the color of the background on the lists but as Lists have been reimplemented in iOS16 this no longer works.
I have solved this for iOS 16 devices by using the new scrollContentBackground modifier:
List() {
some foreach logic here
}
.background(color)
.scrollContentBackground(.hidden)
This works as expected apart from one issue.
When the list is empty the background color is ignored, It shows a white or black background (Not even the grouped background colours) depending on the light or dark mode setting.
Has anybody else come across this issue (or am I doing something wrong?) and if so what solutions have you come up with?
Thanks, C
Upvotes: 10
Views: 3567
Reputation: 3080
here's what I have done
if data.count > 0 {
List()
} else {
Color.clear
}
Upvotes: 9
Reputation: 1
I was looking for the same and I got an idea from @Rhys Morgan answer. When the list is empty, I added a TextView
with empty string and used the .listRowBackground(Color.clear)
with and it worked.
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)
Upvotes: 0
Reputation: 618
May not work for everyone but I have a solute for my own problem.
I am using an overlay to present a message when the list is empty so I decided to do the old ZStack trick in here and it seems to work as expected.
Example:
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!")
}
}
})
Hope this helps somebody else!
Upvotes: 5
Reputation: 123
The unfortunate solution is to add an element to your List
to ensure that it isn't empty.
I found your question while looking it up for myself, and I found that the only way to remove the white/black background from the List
was to add any non-EmptyView
view. However, that doesn't mean it has to be visible, appear on the screen, or display any content.
Try the following:
List {
Group {
ForEach(data, id: \.id) { item in
// do your ForEach logic here
}
if data.isEmpty {
Spacer()
}
}
.listRowBackground(Color.clear)
}
.scrollContentBackground(.hidden)
If Spacer()
doesn't work for you for some reason, try:
Text("ListFix")
.hidden()
.accessibility(hidden: true)
instead, or something along those lines. .accessibility(hidden: true)
is important to add, otherwise it'll read that text to anyone using VoiceOver.
Consider this an opportunity to add some useful empty state message to your List
, perhaps. That's what I ultimately did, moving the empty state inside my List
, rather than wrapping the entire List
in an if !data.isEmpty
condition. But if you don't want an empty state, just adding a single view that you can hide will seem to do the job.
Upvotes: 4