Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Big unwanted space in subview navigation bar

Tags:

ios

swift

swiftui

There is a huge space in my subview navigation bar.

I was assuming by adding trailing buttons, it would align everything nicely to the right of the back button.

This is my main view:

enter image description here

Now this is my subview:

enter image description here

Look at the huge gap at the top. I want the plus button to be to the right of the back button. Do I need to just create a custom back button for this or what?

Here is my code for the subview:

var body: some View {
    NavigationView {
        List {
            Text("hello world")
            Text("hello world")
            Text("hello world")
        }
        .navigationBarTitle(todoList.title!)
        .navigationBarItems(trailing:
            HStack {
                Button(action: {
                    self.add = true
                }, label: {
                    Image(systemName: "plus")
                })
            }
        )
    }
}

I also want to remove the text from the back button so it's just an image.

To summarize:

  • I want the plus button at the top to the right of the back button
  • I want to remove the back button text, which reads ColorTodo in this example

Is there a SwiftUI native way of doing this or do I need a custom back button and to disable the default one?

like image 845
kdion4891 Avatar asked Nov 06 '19 00:11

kdion4891


People also ask

How do I edit my navigation bar?

From Settings, tap Display, and then tap Navigation bar. Make sure Buttons is selected, and then you can choose your desired button setup at the bottom of the screen. Note: This option will also affect the location you swipe when using Swipe gestures.


1 Answers

The reason for the extra space is that you are wrapping a NavigationView inside a NavigationView; remove the one inside your subview, and the plus button will be at the right height.

As for removing the text, yes, you would need to hide the default back button and replace it with your own. Subview might look something like

struct SubView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body: some View {
            List {
                Text("hello world")
                Text("hello world")
                Text("hello world")
            }
            .navigationBarTitle(todoList.title!, displayMode: .inline) // 1
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: backButton, trailing: addButton)
    }

    var backButton: some View {
        Button(action: {
            self.presentationMode.wrappedValue.dismiss()
        }, label: {
            HStack {
                Image(systemName: "chevron.left")
                Text("Back") // 2
            }
        })
    }

    var addButton: some View {
        Button(action: {
            self.add = true
        }, label: {
            ZStack(alignment: .trailing) {
                Rectangle() // 3
                    .fill(Color.red.opacity(0.0001)) // 4
                    .frame(width: 40, height: 40)
                Image(systemName: "plus")
            }
        })
    }
}

Notes:

  1. Although displayMode: .inline is not necessary, the default large title style looks a bit strange animating in and out.
  2. You can remove this if you want (but see below)
  3. This rectangle is here to increase tap target size, as the default button will only be the size of the plus icon, which is probably too small.
  4. The rectangle can't be completely transparent, or it will not register taps.
like image 189
John M. Avatar answered Oct 17 '22 20:10

John M.