PageTabViewStyle shows an additional screen

Im having a rather strange issue, in my main View of the app I have TabViews styled as PageTabViews within which tab items are other 3 Sub Views. Second page has a Navigation View, and while at the main scrolling from first page to second it shows an empty page. I know this sounds confusing, please find the below screen capture explaining the behaviour so that its easier to understand what I am talking about:

ezgif-1-9773ec1163-min

The code to main view:

import SwiftUI

struct AdhaanTimingsMainView: View {
    @EnvironmentObject var DuaModel:DuasViewModel
    @EnvironmentObject var IslandModel:IslandsViewMode
    @EnvironmentObject var AtollModel:AtollsViewModel
    
    var body: some View {
        TabView {
            PrayerTimingsView()
            .tabItem {
                VStack{
                    Image(systemName: "alarm")
                    Text("Prayer Timings")
                        .foregroundColor(Color.primary)
                }
            }
            
            DhuasListView()
            .tabItem {
                VStack{
                    Image(systemName: "list.bullet.rectangle.fill")
                    Text("Duas")
                        .foregroundColor(Color.primary)
                }
            }
            
            SettingsView()
            .tabItem {
                VStack{
                    Image(systemName: "gear.circle")
                    Text("Settings")
                        .foregroundColor(Color.primary)
                }
            }
        }
        .tabViewStyle(PageTabViewStyle())
        .ignoresSafeArea()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        AdhaanTimingsMainView()
            .environmentObject(DuasViewModel())
            .environmentObject(IslandsViewMode())
            .environmentObject(AtollsViewModel())
            .environmentObject(PrayerTimesViewModel())
    }
}

The code to first page

import SwiftUI

struct PrayerTimingsView: View {
    @EnvironmentObject var DuaModel:DuasViewModel
    @EnvironmentObject var IslandModel:IslandsViewMode
    @EnvironmentObject var PrayerTimesModel:PrayerTimesViewModel
    
    @State var todaysDate = ""
    
    
    var body: some View {
        ZStack {
            Image("bg2")
                .resizable()
                .ignoresSafeArea()
            VStack{
                ScrollView{
                    // MARK: HEADER - Home Screen
                    HStack{
                        VStack(alignment: .leading){
                            Text("Adhan Timings")
                                .font(Font.custom("Optima Bold", size: 20))
                            Text(PrayerTimesModel.selectedIslandName)
                                .font(Font.custom("Optima Bold", size: 30))
                            Text(todaysDate)
                                .font(Font.custom("Optima Regular", size: 20))
                            
                        }
                        .padding()
                        Spacer()
                        Image("mosque")
                            .resizable()
                            .scaledToFit()
                            .frame(width:128)
                            .padding(.trailing)
                    }
                    Divider()
                    
                    // MARK: Body - Home Screen
                    VStack(spacing: 50){
                        HStack{
                            Image(systemName: "sun.and.horizon.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Fajr")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.fajr)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "sunrise.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Sunrise")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.sunrise)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "sun.max.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Dhuhr")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.duhr)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "cloud.sun.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Ashar")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.asr)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "sun.haze.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Maghrib")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.maghrib)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "moon.stars.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Isha")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.isha)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                    }
                    .padding()
                    .foregroundColor(Color.gray)
                    
                    if DuaModel.showDhuainHome {
                        Divider()
                        DuaoftheDayView()
                    }
                }
                
            }
            .onAppear{
                todaysDate = String(DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .none))
                // MARK: TODO
                // PrayerTimesModel.updateTodaysPrayerTimes()
            }
        }
    }
        
}

struct PrayerTimingsView_Previews: PreviewProvider {
    static var previews: some View {
        PrayerTimingsView()
            .environmentObject(DuasViewModel())
            .environmentObject(IslandsViewMode())
            .environmentObject(PrayerTimesViewModel())
    }
}

code to the second page:

import SwiftUI

struct DhuasListView: View {
    @EnvironmentObject var DuaModel:DuasViewModel
    
    
    var body: some View {
        NavigationView{
            ZStack {
                Image("bg2")
                    .resizable()
                    .ignoresSafeArea()
                ScrollView{
                    VStack(alignment: .leading, spacing: 10) {
                        Text("Duas")
                            .font(Font.custom("Optima Bold", size: 30))
                        Divider()
                        
                        ForEach(DuaModel.Thasbees){ thasbeeh in
                            NavigationLink {
                                DuasSublistView(duaList: thasbeeh.duas, duaHeading: thasbeeh.name)
                            } label: {
                                Text("• \(thasbeeh.name) - \(thasbeeh.duas.count)")
                                    .font(Font.custom("Optima Regular", size: 20))
                                    .foregroundColor(Color.primary)
                                    .multilineTextAlignment(.leading)
                            }
                        }
                        
                    }
                    .padding([.leading, .bottom, .trailing])
                                              
                }
            }
            .navigationBarHidden(true)
        }
        
    }
}

struct DhuasListView_Previews: PreviewProvider {
    static var previews: some View {
        DhuasListView()
            .environmentObject(DuasViewModel())
    }
}

Code to the third page:

import SwiftUI

struct SettingsView: View {
    @EnvironmentObject var DuaModel:DuasViewModel
    @EnvironmentObject var IslandModel:IslandsViewMode
    @EnvironmentObject var AtollModel:AtollsViewModel
    @EnvironmentObject var PrayerTimesModel:PrayerTimesViewModel
    
    var body: some View {
        
        ZStack {
            Image("bg2")
                .resizable()
                .ignoresSafeArea()
            VStack(alignment: .leading){
                // MARK: Show Dua of the Day Home Screen
                Text("Settings")
                    .font(Font.custom("Optima Bold", size: 30))
                
                Toggle("Show Dua Card in Home Screen", isOn: $DuaModel.showDhuainHome)
                    .font(Font.custom("Optima Regular", size: 20))
                Divider()
                
                // MARK: Location Settings
                HStack{
                    Text("Location: ")
                        .font(Font.custom("Optima Regular", size: 20))
                    
                    Picker("Location", selection: $IslandModel.locationIndex) {
                        ForEach(0..<IslandModel.Islands.count) { islandIndex in
                            
                            var atollObj = AtollsViewModel.getAtoll(atollCode: IslandModel.Islands[islandIndex].atoll_code)
                            
                            
                            Text("\(atollObj.name_abbr_en). \(IslandModel.Islands[islandIndex].name_en)")
                                .tag(islandIndex)
                                .font(Font.custom("Optima Regular", size: 20))
                        }
                    }.pickerStyle(MenuPickerStyle())
                        .onChange(of: IslandModel.locationIndex) { newLocation in
                            PrayerTimesModel.updateTodaysPrayerTimes(locationIndex: newLocation)
                        }

                }
                Spacer()
            }.padding()
        }
    }
}

struct SettingsView_Previews: PreviewProvider {
    static var previews: some View {
        SettingsView()
            .environmentObject(DuasViewModel())
            .environmentObject(IslandsViewMode())
            .environmentObject(AtollsViewModel())
            .environmentObject(PrayerTimesViewModel())
    }
}

The source to whole project is here in case you would want to skim through it:

I would really appreciate if you could assist me figure out where exactly its causing this empty page that we are seeing and how it could be removed.

The problem you are experiencing is to do with how NavigationViews operate post iOS 14.5. I’m not sure how to fix it completely but in the first instance you need to add the modifier .navigationViewStyle(.stack)
to the closing brace of your NavigationView in DhuasListView.
It solves the issue of the blank page but it still looks a bit weird the first time you swipe to the second tab ( DhuasListView() ).

If you revert your TabView to the default Tab Style the issue does not occur but I’m guessing that you didn’t want your TabView to be the default.

As an observation I note that the random prayer that you display at the bottom is partially cut off from view in the opening Tab. It sort of detracts from a relatively clean initial view. Perhaps there is a better way of constructing that view. Try this and see what you think.

struct PrayerTimingsView: View {
    @EnvironmentObject var DuaModel:DuasViewModel
    @EnvironmentObject var IslandModel:IslandsViewMode
    @EnvironmentObject var PrayerTimesModel:PrayerTimesViewModel
    
    @State var todaysDate = ""
    
    
    var body: some View {
        ZStack {
            Image("bg2")
                .resizable()
                .ignoresSafeArea()
            VStack{
                // MARK: HEADER - Home Screen
                HStack{
                    VStack(alignment: .leading){
                        Text("Adhan Timings")
                            .font(Font.custom("Optima Bold", size: 20))
                        Text(PrayerTimesModel.selectedIslandName)
                            .font(Font.custom("Optima Bold", size: 30))
                        Text(todaysDate)
                            .font(Font.custom("Optima Regular", size: 20))

                    }
                    .padding()
                    Spacer()
                    Image("mosque")
                        .resizable()
                        .scaledToFit()
                        .frame(width:128)
                        .padding(.trailing)
                }
                Divider()

                // MARK: Body - Home Screen
                ScrollView {
                    VStack(spacing: 50){
                        HStack{
                            Image(systemName: "sun.and.horizon.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Fajr")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.fajr)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "sunrise.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Sunrise")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.sunrise)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "sun.max.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Dhuhr")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.duhr)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "cloud.sun.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Ashar")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.asr)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "sun.haze.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Maghrib")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.maghrib)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                        
                        HStack{
                            Image(systemName: "moon.stars.fill")
                                .resizable()
                                .scaledToFit()
                                .frame(width: max(24, 48))
                            Text("Isha")
                                .font(Font.custom("Optima Bold", size: 30))
                            Spacer()
                            Text(PrayerTimesModel.TodaysPrayerTimes.isha)
                                .font(Font.custom("Optima Bold", size: 30))
                        }
                    }
                    .padding()
                    .foregroundColor(Color.gray)
                    
                }
                if DuaModel.showDhuainHome {
                    Divider()
                    DuaoftheDayView()
                }
                
            }
            .onAppear{
                todaysDate = String(DateFormatter.localizedString(from: Date(), dateStyle: .long, timeStyle: .none))
                // MARK: TODO
                // PrayerTimesModel.updateTodaysPrayerTimes()
            }
        }
    }
}
1 Like

Perfect @Chris_Parker, exactly what I have been looking for, yes the first time you swipe into the second tab it looks weired but it atleast fixes the issue of empty page which would have cause much chaos. And correct I actually did not want to use the default tab style for the project as it has been a requirement to use the page style.

In regrds to the random dua’s portion at the bottom of the screen, I agree with you and I guess I need to do something such as show a limited number of charectors for it, perhaps a card for the bottom section and when once pressed on the card show a compelete new sheet which contains the complete content of it. I will cook an idea for it and work it out.

Once again thank you so much @Chris_Parker you are such a charm!!!

1 Like