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())
}