Same code different behaviour

Hi all,

I am working on my first app and I am close to publish it. I am working on fixing some bugs currently. I have been trying to solve this bug for a while now with no luck. When in the digesters view page and showing the Site header the title overlaps when pulling down the digester card, also when scrolling up the card the header moves up a bit and the title disappears. This doesn’t happen with the digester header despite the code being as similar as possible. Can someone help please. Thanks.

import SwiftUI

struct SiteHeaderView: View {
    
    var showHeader: Bool
    var site: Site
    
    var body: some View {
        
        if showHeader {
            
            //Page Header
            HStack{
                Image("adsite")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 160, height: 160)
                
                VStack(alignment: .leading, spacing: 10) {
                    Text("Digesters: \(site.digesters.count)")
                    Text("Company: \(site.company)")
                }
            }
            .padding(.horizontal, 30)
            .background{
                RoundedRectangle(cornerRadius: 15)
                    .fill(.headerBg)
                    .ignoresSafeArea()
            }
        }
    }
}
import SwiftUI
import SwiftData
import TelemetryClient

struct DigestersView: View {
    
    @Environment(\.dismiss) private var dismiss
    @Environment(\.modelContext) private var context
    
    @Bindable var defaultElement: DefaultElement
    
    @State private var newDigester: Digester?
    @State private var selectedDigester: Digester?
    @State private var editDigester: Digester?
    @State private var deleteDigester: Digester?
    @State private var showDeleteConfirmation = false
    @State private var isEditMode = false
    
    
   @Bindable var site: Site
    
    var body: some View {
        NavigationStack{
            
            let showHeader = UserDefaults.standard.bool(forKey: "siteHeader")
            
            SiteHeaderView(showHeader: showHeader, site: site)
            
            //Sort Digesters by the tank number from 1 to 5
            let sortedDigesters = site.digesters.sorted(by: { u1, u2 in
                u1.tankNumber < u2.tankNumber
            })
            
            if site.digesters.count == 0 {
                Spacer()
                Image("digester.trianglebadge.exclamationmark")
                    .symbolRenderingMode(.palette)
                    .foregroundStyle(.red, .gray)
                    .font(.system(size: 100))
                Text("No digesters in the list")
                    .font(.headline)
                Text("Add at least one digester")
                    .foregroundStyle(.gray)
                    .font(.subheadline)
                Button("Add Digester") {
                    isEditMode = false
                    newDigester = Digester()
                }
                .buttonStyle(.bordered)
                .padding()
                Spacer()
            }
            else {
                
                List (sortedDigesters) {digester in
                    DigesterCardView(digester: digester)
                        .id(refreshList)
                        .onTapGesture {
                            selectedDigester = digester
                        }
                        .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                            Button (role: .destructive) {
                                deleteDigester = digester
                                showDeleteConfirmation = true
                            } label: {
                                Label("Delete" ,systemImage: "trash")
                            }
                            
                        }
                        .swipeActions(edge: .leading, allowsFullSwipe: false) {
                            Button (role: nil) {
                                editDigester = digester
                                isEditMode = true
                            } label: {
                                Label("Edit" , systemImage: "pencil")
                            }
                            .tint(.yellow)
                        }
                    
                        .listRowSeparator(.hidden)
                }
                .scrollIndicators(.hidden)
                .listStyle(.plain)
            }
        }
        .navigationTitle(site.siteName)
        .navigationDestination(item: $selectedDigester) { digester in
            LabResultsView(digester: digester)
        }
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button {
                    isEditMode = false
                    newDigester = Digester()
                } label: {
                    Image("digester.badge.plus")
                        .symbolRenderingMode(.palette)
                        .foregroundStyle(.green, .gray)
                        .font(.system(size: 20))
                }
            }
        }
        .confirmationDialog("Really delete?", isPresented: $showDeleteConfirmation, titleVisibility: .visible) {
            Button("Yes, delete it", role: .destructive) {
                withAnimation {
                    
                    //Delete data record from SfiftData
                    context.delete(deleteDigester!)
                    
                    //Refresh List
                    refreshList.toggle()
                    
                    //Force swiftdate save
                    try? context.save()
                    
                    TelemetryDeck.signal("Digester", parameters: ["Status" : "Deleted"])
                }
            }
        }
        .sheet(item: $newDigester) { digester in
            AddEditDigesterView(site: site, digester: digester, defaultElement: defaultElement, isEditMode: isEditMode)
        }
        .sheet(item: $editDigester) { digester in
            AddEditDigesterView(site: site, digester: digester, defaultElement: defaultElement, isEditMode: isEditMode)
        }
    }
}
import SwiftUI

struct DigesterHeaderView: View {
    
    var showHeader: Bool
    var digester: Digester
    
    @State private var showTarget: Bool = false
    
    var body: some View {
        
        if showHeader {
            
            //Page Header
            HStack{
                
                ZStack{
                    Image("digester")
                        .symbolRenderingMode(.monochrome)
                        .foregroundStyle(.gray)
                        .font(.system(size: 100))
                    
                    VStack{
                        
                        Text(digester.digesterType)
                            .font(.subheadline)
                            .foregroundStyle(.gray)
                            .padding(.top, 60)
                        
                        
                        Text("\(digester.tankVolume) m3")
                            .font(.subheadline)
                            .foregroundStyle(.gray)
                            .padding(.bottom)
                    }
                    
                }
                
                Spacer()
                VStack(alignment: .leading, spacing: 10) {
                    Text("Lab Samples: \(digester.sampleResults.count)")
                    Text("Dosing Required: \(digester.doseCount)")
                    Toggle("Show Element Target", isOn: $showTarget)
                    
                    if showTarget {
                        
                        //Show Custom or Default Targets
                        Text("Target Type: \(digester.defaultElement ? "Default" : "Custom")")
                        
                        //Nickel
                        let nickelFormatedAverage = digester.defaultElement ? String(format: "%.2f", digester.defaultNickelAverage) : String(format: "%.2f", digester.nickelAverage)
                        Text(String("Nickel: \(nickelFormatedAverage) g/m3 FM"))
                        
                        //Cobalt
                        let cobaltFormatedAverage = digester.defaultElement ? String(format: "%.2f", digester.defaultCobaltAverage) : String(format: "%.2f", digester.cobaltAverage)
                        Text(String("Cobalt: \(cobaltFormatedAverage) g/m3 FM"))
                        
                        //Molybdenum
                        let molybdenumFormatedAverage = digester.defaultElement ? String(format: "%.2f", digester.defaultMolybdenumAverage) : String(format: "%.2f", digester.molybdenumAverage)
                        Text(String("Molybdenum: \(molybdenumFormatedAverage) g/m3 FM"))
                        
                        //Selenium
                        let seleniumFormatedAverage = digester.defaultElement ? String(format: "%.2f", digester.defaultSeleniumAverage) : String(format: "%.2f", digester.seleniumAverage)
                        Text(String("Selenium: \(seleniumFormatedAverage) g/m3 FM"))
                        
                    }
                }
            }
            .padding()
            .background{
                RoundedRectangle(cornerRadius: 15)
                    .fill(.headerBg)
                    .ignoresSafeArea()
            }
            
        }
        
    }
}

import SwiftUI
import SwiftData
import TelemetryClient

struct LabResultsView: View {

@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) private var context

@Bindable var digester: Digester

@State private var newLabResults: LabResults?
@State private var deleteResult: LabResults?
@State private var showDeleteConfirmation = false
@State private var editResult: LabResults?
@State private var selectedLabResults: LabResults?

var body: some View {
    NavigationStack{
        
        let showHeader = UserDefaults.standard.bool(forKey: "digesterHeader")
        
        DigesterHeaderView(showHeader: showHeader, digester: digester)
        
        //Sort sample results by sampling date. Newest on top
        let sortedResults = digester.sampleResults.sorted(by: { u1, u2 in
            u1.sampleDate > u2.sampleDate
        })
        
        if digester.sampleResults.count == 0 {
            Spacer()
            Image("custom.flask.trianglebadge.exclamationmark")
                .symbolRenderingMode(.palette)
                .foregroundStyle(.red, .gray)
                .font(.system(size: 100))
            Text("No sample results in the list")
                .font(.headline)
            Text("Add at least one sample result")
                .foregroundStyle(.gray)
                .font(.subheadline)
            Button("Add Sample Result") {
                newLabResults = LabResults()
            }
            .buttonStyle(.bordered)
            .padding()
            Spacer()
        }
        else {
            List(sortedResults) {result in
                
                SaltRequiredCardView(results: result, digester: digester, doseButton: true, dates: true, showOverdoseValue: false)
                    .onTapGesture{
                        selectedLabResults = result
                    }
                    .id(refreshList)
                    .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                        Button (role: .destructive) {
                            deleteResult = result
                            showDeleteConfirmation = true
                        } label: {
                            Label("Delete" ,systemImage: "trash")
                        }
                    }
                    .swipeActions(edge: .leading, allowsFullSwipe: false) {
                        Button (role: .none) {
                            editResult = result
                        } label: {
                            Label("Edit" , systemImage: "pencil")
                        }
                        .tint(result.dosed ? .gray.opacity(0.1) : .yellow)
                        .disabled(result.dosed)
                    }
                    .listRowSeparator(.hidden)
            }
            .scrollIndicators(.hidden)
            .listStyle(.plain)
        }
    }
    .navigationTitle("Digester \(digester.tankNumber)")
    .navigationDestination(item: $selectedLabResults) { result in
        LabResultDetailView(results: result, digester: digester)
    }
    .toolbar {
        ToolbarItem(placement: .topBarTrailing) {
            Button {
                newLabResults = LabResults()
            } label: {
                Image("custom.flask.badge.plus")
                    .symbolRenderingMode(.palette)
                    .foregroundStyle(.green, .gray)
                    .font(.system(size: 20))
            }
        }
    }
    .sheet(item: $newLabResults) { results in
        AddEditLabResults(digester: digester, labResults: results, isEditMode: false)
    }
    .confirmationDialog("Really delete?", isPresented: $showDeleteConfirmation, titleVisibility: .visible) {
        Button("Yes, delete it", role: .destructive) {
            withAnimation {
                
                if !deleteResult!.dosed && !isOverdosed() && !isElementZero() && dosingRequired() {
                    digester.doseCount -= 1
                }
                
                //Delete data record from SfiftData
                context.delete(deleteResult!)
                
                //Refresh List
                refreshList.toggle()
                
                //Force swiftdate save
                try? context.save()
                
                TelemetryDeck.signal("labResults", parameters: ["Status" : "Deleted"])
            }
        }
    }
    .sheet(item: $editResult) { result in
        AddEditLabResults(digester: digester, labResults: result, isEditMode: true)
    }
}

private func isOverdosed() -> Bool {
    
    
    return deleteResult!.cobaltOverdose && deleteResult!.seleniuOverdose && deleteResult!.molybdenumOverdose && deleteResult!.nickelOverdose
}


private func isElementZero() -> Bool {
    return Double(deleteResult!.nickelRequired) == 0.0 && Double(deleteResult!.cobaltRequired) == 0.0 && Double(deleteResult!.molybdenumRequired) == 0.0 && Double(deleteResult!.seleniumRequired) == 0.0
}

private func dosingRequired() -> Bool {
    return Double(deleteResult!.nickelRequired)! > 0 || Double(deleteResult!.cobaltRequired)! > 0 || Double(deleteResult!.molybdenumRequired)! > 0 || Double(deleteResult!.seleniumRequired)! > 0
}

}