0

I have an app with 3 views. they are connected by a NavigationView and have NavigationLinks that link to the next view. however, all views are created with an extra NavigationBar and with lots of blank white space on the bottom that travels up the screen every time you click through the views and go back to the home page. I remember a few days ago having this issue when I went from the HomeView() to the TimerView() but I'm not sure how I got rid of it. and also I definitely did not get rid of it because I'm still having the same problem. and also I don't remember how I worked around this the first time. I have seen other posts which say I should set the navigationBar color to clear but that does nothing. not sure what is going on. most other posts on this topic are about removing the space up top and very few talk about the blank space on the bottom so I'm not really sure what to do.

I go into the capture view hierarchy and I see that white footer bar is created when the view is created but then just seems to stack on top of every other view until the application is unusable. using Xcode 13.1 and running in simulator on iPhone 12 with iOS 15.0.

here's the video as well as pictures from the capture view hierarchy thing https://i.stack.imgur.com/nI9BQ.jpg

and here's the code

struct ContentView: View {

    @State private var selectedTab = 0
    let numTabs = 2
    let minDragTranslationForSwipe: CGFloat = 50
    @State var secondScreenShown = true

    @State private var tabSelection = 0
    @State private var tappedTwice:Bool = false
    @State private var homeID = UUID()
    var handler: Binding<Int> { Binding (
        get: {self.tabSelection},
        set: {
            if $0 == self.tabSelection {
                tappedTwice = true
                print("tappedTwice = true")
            }
            self.tabSelection = $0
        }

    )}


    init() {
        UITabBar.appearance().isTranslucent = false
    }

    var body: some View {
        TabView(selection:handler) {
            NavigationView {
            HomeView()
                .id(homeID)
                .tabItem {
                  Label("Home", systemImage: "house.fill")
                }.tag(0)
                .onChange(of: tappedTwice, perform: { tappedTwice in
                    guard tappedTwice else { return }
                    homeID = UUID()
                    self.tappedTwice = false
                })
            }

        }
        .edgesIgnoringSafeArea(.all)
        .frame(
            minWidth: UIScreen.main.bounds.width,
            maxWidth: .infinity,
            minHeight: UIScreen.main.bounds.height,
            maxHeight: .infinity,
            alignment: .center
        )
    }
}

here's the HomeView()

    struct HomeView: View {

    @State var secondScreenShown = false
    @State var timerVal = 1
    @State private var chosenSound = "None"
    var times = [1, 2, 3, 4, 5, 10, 15, 20, 30, 45, 60]
    var sounds = ["None", "Creepy Kids", "Conjuring The Dark Ones", "The Forbidden Forest" ]
    
    init() {
        UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
        UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
    }
    
    var body: some View {
 //       NavigationView {
            VStack {
                VStack {
                            VStack {
                                Group {
                                    VStack {
                                    
                                                NavigationLink(
                                                    destination: TimerView(timerScreenShown: $secondScreenShown, timerVal: timerVal, chosenSound: chosenSound, initialTime: timerVal),
                                                    isActive: $secondScreenShown,
                                                    label: {Text("Go")
                                                        
                                                        .font(.title2)
                                                        .padding()
                                                        .frame(minWidth: 250)
                                                        .overlay(
                                                            Capsule(style: .continuous)
                                                                .stroke(Color.black, lineWidth: 3)
                                                        )
                                                    })
                                                    .frame(minWidth: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, maxWidth: 100, alignment: .bottom)
                                                    .padding(.top, 10)
                                        
                                    
                                } // third group
                            }
                    
                } // VStack just outside rectangle
                .frame(
                    maxWidth: .infinity,
                    minHeight: UIScreen.main.bounds.height,
                    maxHeight: .infinity,
                    alignment: .center
                )
                .padding()
 //               ) // rectangle.overlay()
                
            } // VStack
            .edgesIgnoringSafeArea([.top, .bottom])
            .background(Color.pink)
            .frame(
                minWidth: UIScreen.main.bounds.width,
                maxWidth: .infinity,
                minHeight: UIScreen.main.bounds.height,
                maxHeight: .infinity,
                alignment: .center
            )

     //   } // NavigationView
        .navigationViewStyle(StackNavigationViewStyle())
        .navigationBarTitle("main level")
    }
}
}

And here's the TimerView()

    struct TimerView: View {

    @Binding var timerScreenShown:Bool
    @State var timerVal:Int
    @State var chosenSound:String

    @State private var showNextView = false
    @State private var paused = false

    var initialTime:Int

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        
        VStack {
            VStack {
                        VStack {
                                NavigationLink(
                                    destination: HomeView(),
                                    label: {Text("Home Page")})
                                        .font(.title2)
                                        .frame(minWidth: 0,maxWidth: 200, alignment: .center)
                                        .overlay(
                                            Capsule(style: .continuous)
                                                .stroke(Color.black, lineWidth: 3)
                                        )
                                        .padding(.top, 35)

                            //    } // else
                        } // innermost VStack

                        .frame(
                            alignment: .center
                        )
                        .padding()
  //              )

            } // VStack 2
            .frame(
                minWidth: UIScreen.main.bounds.width,
                maxWidth: .infinity,
                minHeight: UIScreen.main.bounds.height,
                maxHeight: .infinity,
                alignment: .center
            )

        } // VStack
        .edgesIgnoringSafeArea([.top, .bottom])
        .background(Color.purple
//            Image("HomePageBackground")
//                .resizable()
//                .ignoresSafeArea()
        )
        .frame(
            minWidth: UIScreen.main.bounds.width,
            maxWidth: .infinity,
            minHeight: UIScreen.main.bounds.height,
            maxHeight: .infinity,
            alignment: .center
        )

        .onAppear(){
            UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
            UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
        }

        .navigationBarTitle("timer view")
    } // View

}

so yeah it's obvious there's extra navigation views being created somewhere but I'm not sure where. it's also obvious that blank space in the footer is created when the view is loaded but I don't know where. so yeah any help would be appreciated.

if there are any brackets/parenthesis missing it's because I accidentally deleted it while removing commented out extraneous code.

zamanada
  • 158
  • 13
  • @Asperi nope. it seems that question is missing code. the rest of the code was uploaded to a repo which redirects to a 404 error. I tried setting the UITabBar.appearance().barTintColor = .systemPink but the app loads with the exact same white bar. the white bar only turns pink if you select the other tab. here's a video https://imgur.com/a/kO72wcM – zamanada Feb 09 '22 at 21:25
  • Try making a a [Minimal, Reproducible Example (MRE)](https://stackoverflow.com/help/minimal-reproducible-example). There is a great deal of code here, that doesn't need to be here, but we need to be able to run the code. – Yrb Feb 09 '22 at 21:28
  • 1
    You are pushing navigation links to HomeView, which has a NavigationView in it, resulting in multiple NavigationViews in the hierarchy. You need to have one parent view (that never gets pushed again) that contains the NavigationView. – jnpdx Feb 09 '22 at 21:33
  • @Yrb on first look I have removed all the code that references methods outside of the provided code. but if that's still too much I will do a bulk delete. – zamanada Feb 09 '22 at 21:33
  • @jnpdx any suggestions on how that would be implemented? my first thought is to put that in the ContentView() – zamanada Feb 09 '22 at 21:34
  • Yes, that would be reasonable – jnpdx Feb 09 '22 at 21:36
  • @jnpdx okay so I've solved the navigation bar getting constantly added on but the bar on the bottom of the screen is now grey. and instead of showing up when I click from TimerView() to HomeView() it shows up when I go from the HomeView() to the TimerView(). also the TabItem for the HomeView disappeared and no longer functions – zamanada Feb 09 '22 at 21:51
  • If you pare everything down to a [mre] that represents the issue and nothing extraneous, I or someone else can give you a concrete code solution – jnpdx Feb 09 '22 at 21:54
  • @jnpdx I thought I did in my most recent edit? is there anything there still giving you issues? – zamanada Feb 09 '22 at 21:56
  • @zamanada copying and pasting into a blank Xcode project leads to compilation errors. Plus, it's far from minimal -- does it need the gestures to represent the issue? The AVAudioPlayer? The custom colors? Everything that isn't necessary should be removed. That way, it's easier for an answerer and much easier for a future reader if they have a similar issue and they're just trying to see what the changes are. – jnpdx Feb 09 '22 at 22:01
  • The problem with tab at the bottom may be the same as the one for navigation bar. What is stable on alls screen should be define in first view (usually contentview) so home view should not contains the tabview. – Ptit Xav Feb 09 '22 at 22:38
  • @jnpdx I have made the changes. it should be minimal workable code. if it isn't I'll just upload it to GitHub – zamanada Feb 09 '22 at 22:48
  • @PtitXav yes you are right. it should not. so do you know why it does because I dont – zamanada Feb 09 '22 at 23:04
  • Nope -- doesn't compile. You can test yourself by pasting into a blank project. I did notice that you removed the items I mentioned, but there is still a ton of code that is unlikely to be related to the issue. Please, try to pare down everything unnecessary. One of the benefits of doing this is you may find the issue on your own, too -- this happened to me last time I went to post a question. – jnpdx Feb 09 '22 at 23:10
  • @jnpdx any compilation errors in particular? – zamanada Feb 09 '22 at 23:12
  • Missing braces. You can test yourself by pasting into a blank project – jnpdx Feb 09 '22 at 23:13
  • @jnpdx If you're talking about the extra brace in the HomeView() struct after the second navigation link I just got it. and then I ran it in an empty project and it worked. – zamanada Feb 09 '22 at 23:20
  • Please review my comment about removing all of the unnecessary code. I can't spend any more time here now, but that'll get you on the right track. – jnpdx Feb 09 '22 at 23:24
  • @jnpdx is there anyway you could be more specific about what you mean by "unnecessary code"? I just had my last question on my TabBar go unanswered because the commenter said I didn't include enough code. at the very least I'd like to know what to remove so that others could help – zamanada Feb 09 '22 at 23:25
  • Unnecessary code is code that isn't necessary to to directly represent the issue at hand. I've given you examples already that you've removed. Now, you have to find the other elements that you can take out. – jnpdx Feb 09 '22 at 23:27
  • @jnpdx I'm confused. can you not help because you're getting errors or are you not helping me because I've included extraneous code? – zamanada Feb 09 '22 at 23:28
  • @jnpdx and that's not what I meant when I asked you to be more specific. if there is code you think is irrelevant I'd like to know which code specifically. I thought I included the bare bones. – zamanada Feb 09 '22 at 23:36
  • 1
    I worked on it for a while and got it down to a 60-line [mre] that still represented the issue. It then became apparent that the bottom issue is a result of your `UITabBar.appearance().isTranslucent = false`. If you remove that, the issue of the extra bottom space goes away. So, I guess the question becomes do you absolutely need that *or* can you (or someone) find a workaround. Here's what the MRE would look like, so you can see what it would look like pared down: https://gist.github.com/jnpdx/ce49d1b043bd104b41e6e036e74f4b10 – jnpdx Feb 10 '22 at 01:08
  • @zamanada : I think you may have a conception problem about what you want to do : getting more end more homeview and timerview? Or having just 3 views that you go through ? – Ptit Xav Feb 10 '22 at 07:34
  • @jnpdx thank you thank you thank you!!! that solved it. thanks so much!!!!!! if you want to put it as like an answer I can mark you correct – zamanada Feb 10 '22 at 20:35
  • @zamanada done -- glad it worked for you. Does looking at the code I provided make it more clear about what a minimal example looks like? It can be really helpful to be able to break things down into that state in order to get help here. – jnpdx Feb 10 '22 at 20:41

1 Answers1

1

The issue is caused by the UITabBar.appearance().isTranslucent = false line -- without that, as you confirmed in the comments, it behaves as expected.

Here's a working version with a note about that line:

import SwiftUI

struct ContentView: View {
    
    init() {
        UITabBar.appearance().isTranslucent = false //REMOVE THIS and functionality will be as-expected
    }
    
    var body: some View {
        TabView {
            NavigationView {
                HomeView()
            }.tabItem {
                Label("Home", systemImage: "house.fill")
            }
            .navigationViewStyle(StackNavigationViewStyle())
            .tag(0)
        }
    }
}

struct TimerView: View {
    var body: some View {
        VStack {
            NavigationLink(
                destination: HomeView(),
                label: {Text("Home Page")})
        }
        .padding()
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
        .background(Color.purple)
        .edgesIgnoringSafeArea([.top, .bottom])
        
        .navigationBarTitle("timer view")
    }
    
}

struct HomeView: View {
    var body: some View {
        VStack {
            NavigationLink(
                destination: TimerView(),
                label: {
                    Text("Go")
                })
                .frame(minWidth: 0, maxWidth: 100, alignment: .bottom)
                .padding(.top, 10)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.pink)
        .edgesIgnoringSafeArea([.top, .bottom])
        .navigationBarTitle("main level")
    }
}
jnpdx
  • 45,847
  • 6
  • 64
  • 94