How to remove default padding from navigationbar (trailing)

Viewed 1559

I'm adding some buttons to the navigationbar in SwiftUI and because I need to add some padding to them, they are displayed more to the left than I intend (as seen below).

enter image description here

I can fix this if I remove the individual padding from each button, but in that case the tap area is very limited and unusual from an UX perspective.

Is there a way to remove the default extra padding?

.navigationBarItems(
        trailing:
            HStack(alignment: .center, spacing: 0) {
                Button(action: {

                }) {
                    Image(systemName: "trash")
                    .imageScale(.large)
                    .accessibility(label: Text("Delete"))
                    .padding()
                }

                Button(action: {

                }) {
                    Image(systemName: "square.and.arrow.up")
                    .imageScale(.large)
                    .accessibility(label: Text("Share"))
                    .padding()
                }

                CustomEditButton() {
                    if self.mode?.wrappedValue == .active {
                        return self.triggerSave()
                    } else {
                        return true
                    }
                }
            }
    )
3 Answers

I would use .padding(.trailing) for "Delete" and "Share" buttons, and don't use any padding for CustomEditButton at all.

And here is result

demo

try this (copy - paste - run)

import SwiftUI

struct DestinationView: View {
    let txt: String
    var body: some View {
        Text(txt)
            .navigationBarTitle(txt)
        .navigationBarItems(trailing:
            HStack {
                Button(action: {
                    print("tap trasgh")
                }) {
                    Image(systemName: "trash")
                }
                Button(action: {
                    print("tap in")
                }) {
                    Image(systemName: "square.and.arrow.down")
                }
                Button(action: {
                    print("tap out")
                }) {
                    Image(systemName: "square.and.arrow.up")
                }
            }.imageScale(.large).padding(.vertical, 8).padding(.horizontal, 3)//.border(Color.blue)
        )
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: DestinationView(txt: "Destination 1")) {
                    Text("Destination 1")
                }
                NavigationLink(destination: DestinationView(txt: "Destination 2")) {
                    Text("Destination 2")
                }
            }
        }.navigationBarTitle("title")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

enter image description here

I found the below workaround that suits my needs. It's not perfect, but at least the tappable area is sufficient and it's looks decent.

enter image description here

HStack(alignment: .center, spacing: 0) {
     Button(action: {
          ////
     }) {
          Image(systemName: "trash")
              .imageScale(.large)
              .accessibility(label: Text("Delete"))
              .padding(.vertical)
              .padding(.horizontal, 8)
     }

     Button(action: {
          ////
     }) {
          Image(systemName: "trash")
              .imageScale(.large)
              .accessibility(label: Text("Delete"))
              .padding(.vertical)
              .padding(.horizontal, 8)
     }

     Button(action: {
          ////
     }) {
          Image(systemName: "trash")
              .imageScale(.large)
              .accessibility(label: Text("Delete"))
              .padding(.vertical)
              .padding(.leading, 8)
              .padding(.trailing, 4)
     }
}                  
Related