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.