Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to automatically detect NavigationBarTitle displayMode become .inline or .large in SwiftUI?

I have a List inside a navigationView and I want to change the List Section text whenever the list is scrolled and the navigationBarTitle become .inline or .large

This is my code:

import SwiftUI

struct ContentView: View {

@State private var scrolledUp = false

var body: some View {

    NavigationView {

        if scrolledUp {

            List {
                Section(header: Text("Moved UP"))
                {
                    Text("Line1").bold()
                    Text("Line2").bold()
                    Text("Line2").bold()

                }

                .navigationBarTitle("Setting")
            }

        } else {

            List {
                Section(header: Text("Not Moved"))
                {
                    Text("Line1").bold()
                    Text("Line2").bold()
                    Text("Line2").bold()

                }
            }
            .navigationBarTitle("Setting")
        }  
     }
   }
}

how can I find out the list is scrolled and the navigationBar is changed to .title?

like image 861
FRIDDAY Avatar asked Oct 17 '25 04:10

FRIDDAY


1 Answers

Here is a rough implementation used to turn on additional nav bar items when it turns from .large to .inline. It is not perfect, but it is enough for some situations.

import SwiftUI

struct ContentView: View {
    @State private var navIsInline = false
    var body: some View {
        NavigationView {
            ScrollView {
                ZStack {
                    LazyVStack {
                        ForEach(1..<100) { val in
                            Text("Hello, NavBar! \(val)")
                        }
                    }
                    GeometryReader { proxy in
                        let offset = proxy.frame(in: .named("scroll")).minY
                        Color.clear.preference(key: ViewOffsetKey.self, value: offset)
                    }
                }
            }
            .coordinateSpace(name: "scroll")
            .onPreferenceChange(ViewOffsetKey.self) { value in
                print(value)
                if navIsInline != (value < 0) {
                    navIsInline.toggle()
                }
            }
            .navigationBarTitleDisplayMode(.large)
            .navigationTitle("Nav title")
            .toolbar {
                if navIsInline {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Text("leading")
                    }
                    ToolbarItem(placement: .navigation) {
                        Text("Navigation")
                            .font(.headline)
                    }
                    ToolbarItem(placement: .navigationBarTrailing) {
                        HStack {
                            Text("Trailing").font(.headline)
                        }
                        .padding(.horizontal)
                    }
                }
            }
            //.toolbar(navIsInline ? .hidden : .visible, for: .navigationBar)
        }
    }
}

struct ViewOffsetKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}
like image 157
Paul B Avatar answered Oct 19 '25 19:10

Paul B



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!