Struggling to hide the SwiftUI separators in a List or Form?
The challenge
Creating the following form, separation lines appeared between NameLayout, FinalPhoto, RawPhoto, ApertureLayout and SubmitButton.
var body: some View {
GeometryReader { geometry in
Form {
// layout elements
NameLayout()
FinalPhoto()
RawPhoto()
ApertureLayout()
SubmitButton()
}
}
}
What was assessed
separatorStyle = .none
At first I tried adding a style none to remove all separators in the init()
UITableView.appearance().separatorStyle = .none
But no they didn't go away.
separatorColor = .clear
Changing the color of the separator to clear in the init()
UITableView.appearance().separatorColor = .clear
But no they didn't go away.
ViewModifier - Style
What about if I try a ViewModifier and managing the separator style for the actual element?
struct ListSeparatorStyle: ViewModifier {
let style: UITableViewCell.SeparatorStyle
func body(content: Content) -> some View {
content
.onAppear() {
UITableView.appearance().separatorStyle = self.style
}
}
}And to the View extension adding
func listSeparatorStyle(style: UITableViewCell.SeparatorStyle) -> some View {
ModifiedContent(content: self, modifier: ListSeparatorStyle(style: style))
}Finally to the Form add the modifier
Form {
// ... code ... //
}
.listSeparatorStyle(style: .none)No - the separator line would not go away!
Success - they are gone
ViewModifier row separator
Adding a ViewModifier as in the above example, was a step in the right direction. However, rather than editing the UITableView, something else was needed to be addressed.
In the ViewModiferExtension.swift file
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: Self.defaultListRowHeight,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets {
static let defaultListRowInsets = Self(top: 0, leading: 16, bottom: 0, trailing: 16)
}
Then in the ViewExtension.swift file add
func hideRowSeparator(
insets: EdgeInsets = .defaultListRowInsets,
background: Color = .white
) -> some View {
modifier(HideRowSeparatorModifier(
insets: insets,
background: background
))
}
Now back to the form, all that you need to add is .hideRowSeparator(). Such as:
Form {
// layout elements
NameLayout()
.hideRowSeparator()
FinalPhoto()
.hideRowSeparator()
RawPhoto()
.hideRowSeparator()
ApertureLayout()
.hideRowSeparator()
SubmitButton()
}Test and check... the separators should now be gone.