1

I am currently creating a content view for my application and am experiencing some strange behavior with padding. As seen in the photo below, there is quite a bit of space below the navigation bar at the top of the phone. I don't specify any padding here so I'm wondering why there is so much space between the top and where the image is displayed. The image doesn't have that large of a white box around it either.

My code does not specify any kind of margin or padding. I'm new to Swift and SwiftUI so I'm curious if there is some automatic padding applied to navigation views?

import Kingfisher

struct BottleView: View {
    let bottle: Bottle

    var body: some View {
        VStack {
            KFImage(URL(string: bottle.image ?? "")!)
             .resizable()
            .frame(width: 128, height: 256)

            VStack(alignment: .leading) {
                HStack {
                    Text(bottle.name)
                        .font(.title)
                    Spacer()
                    Text("Price")
                }

                HStack {
                    Text(bottle.varietal ?? "")
                    Spacer()
                    Text("$\(bottle.price ?? "")")
                }
                .font(.subheadline)
                .foregroundColor(.secondary)

                VStack(alignment: .leading) {
                    Text("Information")
                        .font(.title2)
                    Text(bottle.information ?? "")
                }
            }
        }
    }
}
Image with text underneath, but everything is centered in the screen

1 Answer 1

3

If you apply a .background(Color.red) to the VStack, you'll see that it's centered in the screen.

var body: some View {
    VStack {
        Image("TestImage")
        .resizable()
        .frame(width: 128, height: 256)

        /// ... more code
    }
    .background(Color.red)
}
Red rectangle behind all views, with considerable gap between top and bottom of the screen

This is because, by default, most SwiftUI views are centered. For example, try just a Text:

struct ContentView: View {
    var body: some View {
        Text("Hello, I'm centered!")
    }
}
Text 'Hello, I'm centered!' centered in the screen

So if you don't want it centered, this is where Spacers come in. These expand to fill all available space, pushing all other views. Here's the code that gets rid of the "bit of space below the navigation bar at the top of the phone":

(note that I replaced your Bottle properties with static text, make sure you change them back)

struct BottleView: View {
//    let bottle: Bottle
    
    var body: some View {
        VStack {
            Image("TestImage")
                .resizable()
                .frame(width: 128, height: 256)
            
            VStack(alignment: .leading) {
                HStack {
                    Text("Blantons")
                        .font(.title)
                    Spacer()
                    Text("Price")
                }
                
                HStack {
                    Text("Bourbon")
                    Spacer()
                    Text("$59.99")
                }
                .font(.subheadline)
                .foregroundColor(.secondary)

                VStack(alignment: .leading) {
                    Text("Information")
                        .font(.title2)
                    Text("Product info here")
                }
            }
            
            Spacer() /// spacer right here! pushes the other views up
        }
        .background(Color.red)
        .navigationBarTitleDisplayMode(.inline) /// get rid of the additional top gap that the default Large Title navigation bar produces
    }
}

Result:

Red background under all views, with no gap between top navigation bar and bottom home indicator. If `BottleView` wasn't embedded in a NavigationView, there would be no gap at all.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.