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

How do I embed a ScrollView in a NavigationStack?

Forums > Swift

Hello,

I am having trouble embedding a ScrollView in a NavigationStack or NavigationView. The ScrollView does not extend to the bottom of the screen. If I remove the NavigationStack the ScrollView works as expected. I have added .ignoresSafeArea() and .ignoresSafeArea(edges: .all) on both the ScrollView and the NavigationStack and tried wrapping the ScropllView in a ZStack, but nothing seems to change the behavior.

Does anyone have any advice on how this can. be done or what i can try?

I have attached a link that shows the issue. Thanks for any help!!!

Here is my View:

    var body: some View
    {
        NavigationStack {
            ScrollView {
                let columns = [
                    GridItem(.fixed(imageWidth), spacing: colEndPadding),
                    GridItem(.fixed(imageWidth), spacing: colEndPadding),
                    GridItem(.fixed(imageWidth), spacing: colEndPadding)
                ]
                LazyVGrid(columns: columns, spacing: colEndPadding) {
                    ForEach(0..<18, id: \.self) { index in
                        Rectangle()
                            .foregroundColor(Color(
                                red: .random(in: 0...1),
                                green: .random(in: 0...1),
                                blue: .random(in: 0...1),
                                opacity: 1.0
                            ))
                            .frame(width: imageWidth, height: imageHeight)
                    }
                }
                .padding(.horizontal)
            }
            .edgesIgnoringSafeArea(.all)
            .navigationBarHidden(false)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Menu(content: {
                        MoreMenuButtonTextWithImage(label: "Option 1", systemImageName: "folder.badge.plus") { }
                        MoreMenuButtonTextWithImage(label: "Option 2", systemImageName: "folder.badge.plus") { }
                        MoreMenuButtonTextWithImage(label: "Option 3", systemImageName: "folder.badge.plus") { }

                        Divider()

                        MoreMenuButtonText(label: "Option A") { }
                        MoreMenuButtonText(label: "Option B") { }
                        MoreMenuButtonText(label: "Option C") { }
                    }, label: {
                        Image(systemName: "ellipsis.circle")
                            .foregroundColor(Color("allstar_Ice"))
                    })
                }
            }
            .navigationBarTitleDisplayMode(.inline)
            .toolbarBackground(.visible, for: .navigationBar)
        }
        .edgesIgnoringSafeArea(.all)
        .background(
            GeometryReader { geometry in
                Color.clear
                    .onAppear {
                        let screenWidth: CGFloat = geometry.size.width
                        let cols = 3.0
                        imageWidth = (screenWidth - (colEndPadding * (cols - 1))) / 3
                        imageHeight = (((screenWidth - (colEndPadding * (cols - 1))) / 3) * 16) / 9
                        Self.log.info("Line: \(#line), File: \(#file), Function: \(#function): \(#file):\(#function):\(#line), *** imageWidth=\(imageWidth), imageHeight=\(imageHeight)")
                    }
            }
        )
    }

1      

I'm not sure if I understand the issue however done this. Works fine

struct ContentView: View {
    let columns = Array(repeating: GridItem(.flexible(), spacing: 3), count: 3)

    var body: some View {
        TabView {
            NavigationStack {
                ScrollView {
                    LazyVGrid(columns: columns, spacing: 3) {
                        ForEach(0..<18, id: \.self) { _ in
                            Rectangle()
                                .foregroundStyle(
                                    Color(
                                        red: .random(in: 0...1),
                                        green: .random(in: 0...1),
                                        blue: .random(in: 0...1),
                                        opacity: 1.0
                                    )
                                )
                                .containerRelativeFrame(.vertical) { size, axis  in // <- use this for the height
                                    size * 0.3
                                }
                        }
                    }

                }
                .padding(.horizontal)
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    Button("Menu Button here", systemImage: "ellipsis.circle") { }
                }
            }
            .tabItem { Label("Example", systemImage: "house") }
        }
    }
}

1      

Yes, thank you. I should have tried it in a new project. It turns out I am doing this nmy init and for some reason one of these is causing the issue. I will investigate more, but I am all set now:

    init() {
        UITabBar.appearance().isHidden = false
        UITabBar.appearance().backgroundColor = UIColor(named: "midnightDark")
        UITabBar.appearance().unselectedItemTintColor = UIColor(named: "chalkAlpha45")
        UITabBar.appearance().isTranslucent = false
        UITabBar.appearance().barTintColor = UIColor(named: "midnightDark")
    }

1      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

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.