如何在SwiftUI中自动检测NavigationBarTitle显示模式变为.inline或.lage



我在navigationView中有一个List,每当滚动列表并且navigationBarTitle变成.inline.large时,我想更改ListSection文本

这是我的代码:

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")
}  
}
}
}

我怎么能发现list被滚动,而navigationBar被更改为.title

目前我使用geometryReader来检测Listsectionheader的y位置。在滚动过程中。如果位置小于80,则navigationBarTitle变为.title

它工作得很好。然而,我仍在寻找更好的解决方案。

以下是一个粗略的实现,用于在从.large转到.inline时打开其他导航栏项目。它并不完美,但在某些情况下已经足够了。

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()
}
}

相关内容

  • 没有找到相关文章

最新更新