SwiftUI Scrollable View Backgrounds

A quick tip on changing the background of SwiftUI scrollable views like lists and forms.

Scrollable View Default Backgrounds

SwiftUI has several scrollable views such as ScrollView, List, Form, and Table. Here’s my SwiftUI form with a multi-line text field:

Form {
  Section("Your details") {
    TextField("email", text: $email, axis: .vertical)
      .lineLimit(3)
    }

    Section("Feedback") {
      TextEditor(text: $text)
    }
}

This shows up with a gray background by default:

Feedback form on an iPhone 14 Pro with a light gray background

What’s confusing is that you cannot change that light gray default background by applying a background modifier. For example, this has no effect:

Form { ...
}
.background(Color.cyan.gradient,
  in: RoundedRectangle(cornerRadius: 8))

I’m using a Form but the same problem exists with the other SwiftUI scrollable views like List. Why doesn’t it just work?

Hiding the default

The problem is that SwiftUI scrolling views like List and Form all have a default system background. Adding our own background has no visible effect as it’s hidden by the system background.

Apple added a new modifier in iOS 16 that allows you to change the visibility of the system background of scrollable views. Changing the visibility to .hidden allows my cyan background to show through:

Form { ...
}
.scrollContentBackground(.hidden)
.background(Color.cyan.gradient,
  in: RoundedRectangle(cornerRadius: 8))

Feedback form on an iPhone 14 Pro with a cyan background

Lists No Longer Use Table Views (iOS 16)

A word of warning. In the past SwiftUI Lists and Forms used a UITableView for their iOS implementation. This allowed a quick workaround by overriding the table view appearance to clear the default background:

UITableView.appearance().backgroundColor = .clear

That no longer works in iOS 16. From the iOS 16 release notes:

The implementation of list no longer uses UITableView. (81571203)

Use the .scrollContentBackground modifier instead.