I'm not sure if this is well-known-issue or not but it is very odd. The problem can be reproduced with Apple's example code navigationBarItems(leading:trailing:) As you can see, list separators have extra leading space that look like they are indented for some reason.
Here is actual code:
import Foundation
import SwiftUI
import UIKit
import PlaygroundSupport
struct ContentView: View {
var body: some View {
NavigationView {
List {
Text("Chocolate")
Text("Vanilla")
Text("Strawberry")
}
.navigationBarTitle(Text("Today‘s Flavors"))
.navigationBarItems(leading:
HStack {
Button("Hours") {
print("Hours tapped!")
}
}, trailing:
HStack {
Button("Favorites") {
print("Favorites tapped!")
}
Button("Specials") {
print("Specials tapped!")
}
}
)
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
I test above code with Playground, iPhone 13/15.3.1 they are the same. I did messing around the code and found that applying .navigationBarTitle(), .navigationBarItems() to List causes the problem. They must apply to each List item. Very odd though. This means almost all List sample code that wrapping with NavigationView are WRONG. Here is a fix I found.
import Foundation
import SwiftUI
import UIKit
import PlaygroundSupport
struct ContentView: View {
let contents = ["Chocolate", "Vanilla", "Strawberry"]
var body: some View {
NavigationView {
List {
ForEach (contents, id: \.self) { content in
Text(content)
.navigationBarTitle(Text("Today‘s Flavors"))
.navigationBarItems(leading:
HStack {
Button("Hours") {
print("Hours tapped!")
}
}, trailing:
HStack {
Button("Favorites") {
print("Favorites tapped!")
}
Button("Specials") {
print("Specials tapped!")
}
}
)
}
}
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
Although I'm not sure if I can call this is a bug but definitely either document or implementation is wrong. Could anyone explain this?
navigationBarItems
will be deprecated in the future so you should use toolbar
instead
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("Hours") { }
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
HStack {
Button("Favorites") { }
Button("Specials") { }
}
}
}
If you want to keep using navigationBarItems
, there is a better work around by using other ListStyle
struct ContentView: View {
var body: some View {
NavigationView {
List {
Text("Chocolate")
Text("Vanilla")
}
.navigationBarTitle(Text("Today‘s Flavors"))
.navigationBarItems(
leading: Button("Hours") { }
)
.listStyle(PlainListStyle())
}
}
}
do not apply navigationBarTitle
on every row for a work around, it's bad