UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Why is my view in a different position inside ContentView?

Forums > SwiftUI

Beginner question: why does my Home view align differently when I preview it on its own, compared to when I preview it in ContentView?

When previewing Home() on its own, in a iPhone 15 Pro canvas, the top of the .border(.white, width: 1) aligns right at the top of the Dynamic Island area.

When previewing that view inside ContentView, that same line is off the top of the canvas. Why?

I have a ContentView with this structure:

struct ContentView: View {
    // Initialise the menu state
    @State var menuState = SportMenuStatus()
    @State private var tab = 0

    var body: some View {
        ZStack(alignment: .topLeading) {
            TabView(selection: $tab) {
                Group {
                    Home()
                        .tabItem {
                            Image(tab == 0 ? "nav-home-selected" : "nav-home")
                            Text("Home")
                        }
                        .tag(0)

                }
                .toolbarBackground(.ultraThinMaterial, for: .tabBar)
                .toolbarBackground(.visible, for: .tabBar)
                .toolbarColorScheme(.dark, for: .tabBar)
            }
        }
        .edgesIgnoringSafeArea(.top)
        .edgesIgnoringSafeArea(.bottom)
        .environment(menuState)
    }
}

#Preview {
    ContentView()
        .edgesIgnoringSafeArea(.top)
        .edgesIgnoringSafeArea(.bottom)
}

And my Home() view looks like this (sorry this is long, left everything in just in case it is affecting it):

struct Home: View {
    @State private var stackPath: [String] = []
    @Environment(SportMenuStatus.self) var menuState

    var body: some View {
        NavigationStack(path: $stackPath) {
            ZStack() {
                HStack(alignment: .top) {
                    ScrollView {
                        VStack(alignment: .leading, spacing: 0) {
                            VStack(spacing: 0) {
                                CarouselPod()
                            }
                            .background(
                                LinearGradient(gradient: Gradient(stops: [
                                    .init(color: Color("green-156E51"), location: 0),
                                    .init(color: Color("green-156E51"), location: 0.8),
                                    .init(color: Color("green-156E51").opacity(0.0), location: 1),
                                ]), startPoint: .top, endPoint: .bottom)
                            )
                            VStack {
                                PopularItemsPanel()
                                ZStack {
                                    ClassificationRibbon()
                                    HStack(spacing: 0) {
                                        Spacer()
                                        Button(action: {
                                            menuState.isSportMenuShowing.toggle()
                                            print("clicks,\(menuState.isSportMenuShowing)")
                                        }) {
                                            HStack {
                                                Image("icon-hamburger")
                                                Text("All")
                                                    .foregroundStyle(Color("green-28FFBB"))
                                                    .fontWeight(.bold)
                                                    .font(.system(size: 11))
                                            }
                                            .padding(15)
                                            .background(Color("grey-222222").opacity(0.95))
                                            .overlay(
                                                RoundedRectangle(cornerRadius: 15)
                                                    .stroke(Color.white.opacity(0.25), lineWidth: 1))
                                            .cornerRadius(15)
                                        }
                                        .padding(.trailing, 10)
                                    }
                                }
                                .padding(.bottom, 20)
                            }
                            BetBoostPanelView()
                            BetBoostPanelView()
                            Spacer()
                        }
                        .background(Color("grey-222222"))
                    }
                    .safeAreaInset(edge: .top, content: {
                        VStack(alignment: .center) {
                        ZStack {

                                HStack {
                                    Image("icon-logo")
                                }
                                HStack {
                                    Spacer()
                                    Text("Log In")
                                        .padding(10)
                                        .foregroundColor(.white)
                                        .overlay(
                                            RoundedRectangle(cornerRadius: 15)
                                                .stroke(Color.white.opacity(0.25), lineWidth: 1))
                                        .fontWeight(.bold)
                                        .font(.system(size: 11))
                                        .cornerRadius(15)
                                }
                                .padding(.trailing, 10)
                            }
                        }
                        .frame(height: 50)
                        .background(Color("green-156E51"))
                        .zIndex(10.0)
                        .border(.white, width: 1)
                    })
                    .background(Color("green-156E51"))
                }
                .edgesIgnoringSafeArea(.bottom)
                .navigationDestination(for: String.self) { route in
                    switch route {
                    case "SportSplash":
                        SportSplash(path: $stackPath)
                            .navigationBarBackButtonHidden(true)
                    default:
                        EmptyView()
                    }
                }
                .onChange(of: stackPath) { oldValue, newValue in
                    print(newValue)
                }
                SportMenu(path: $stackPath)
            }
        }
    }
}

#Preview {
    Home()
        .environment(SportMenuStatus())
}

   

Because you have TabView in ContentView.

Wrap a TabView around the Home() in the #Preview

#Preview {
  TabView {
    Home()
     .tabItem { Text("Home") }
  }
  .environment(SportMenuStatus())
}

1      

Hallelujah and pass the biscuits! Thanks @NigelGee, that has alluded me for days!

   

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.