How To Change List Color in SwiftUI on iOS 16 with Minimum Deployment of iOS 14
Problem Description:
I’ve developed an app in SwiftUI using a minimum deployment of iOS 14. I have a custom background color which I’ve always created using a ZStack approach. This has worked well until iOS 16 and Xcode 14.
Historically this worked.
struct ContentView: View {
var body: some View {
UITableView.appearance().backgroundColor = .clear
UICollectionView.appearance().backgroundColor = .clear
return ZStack {
Color(.blue)
.edgesIgnoringSafeArea(.all)
VStack {
Text("Hello World")
List {
Text("Item1")
Text("Item2")
} // List
.listStyle(InsetGroupedListStyle())
} // VStack
} // ZStack
}
}
When this is built in iOS 16 in the simulator I see the following. On device the background color is correct. I don’t like that the simulator shows the wrong color. It could be a bug in the simulator but this doesn’t seem right.
In iOS 16 the new fix is to place the following modifier on the List.
.scrollContentBackground(.hidden)
Full code for iOS 16.
struct ContentView: View {
var body: some View {
UITableView.appearance().backgroundColor = .clear
UICollectionView.appearance().backgroundColor = .clear
return ZStack {
Color(.blue)
.edgesIgnoringSafeArea(.all)
VStack {
Text("Hello World")
List {
Text("Item1")
Text("Item2")
} // List
.listStyle(InsetGroupedListStyle())
.scrollContentBackground(.hidden)
} // VStack
} // ZStack
}
}
This works great. Image below.
My issue is that with a minimum deployment of iOS 14 the added scrollContentBackground(.hidden) throws an error stating this is only available in iOS 16. Any thoughts on working around this with iOS 16 with a minimum deployment of iOS 14 would be greatly appreciated.
Solution – 1
I followed the tutorial referenced above and wanted to provide the code below for anyone with the same question.
import Foundation
import SwiftUI
public struct Backport<Content> {
public let content: Content
public init(_ content: Content) {
self.content = content
}
}
extension View {
var backport: Backport<Self> { Backport(self) }
}
extension Backport where Content: View {
@ViewBuilder func scrollContentBackground(_ visibility: Visibility) -> some View {
if #available(iOS 16, *) {
content.scrollContentBackground(visibility)
} else {
content
}
}
}
In use on List
var body: some View {
UITableView.appearance().backgroundColor = .clear
UICollectionView.appearance().backgroundColor = .clear
return ZStack {
Color(.blue)
.edgesIgnoringSafeArea(.all)
VStack {
Text("Hello World")
List {
Text("Item1")
Text("Item2")
} // List
.listStyle(InsetGroupedListStyle())
.backport.scrollContentBackground(.hidden)
} // VStack
} // ZStack
}
This works perfectly.