Sim*_*eil 5 xcode list swiftui
因此,过去我一直使用滚动视图跟踪滚动位置,但我陷入了需要使用列表跟踪位置的情况。我使用列表是因为我想要一些内置的空间来创建我的视图,例如默认的列表样式。
我可以使用 PreferenceKeys 获取该值,但问题是当我向上滚动到远处时,PreferenceKey 值将默认返回到其位置 0,从而破坏了我的 show shy 标题视图逻辑。
这是TrackableListView代码
struct TrackableListView<Content: View>: View {
let offsetChanged: (CGPoint) -> Void
let content: Content
init(offsetChanged: @escaping (CGPoint) -> Void = { _ in }, @ViewBuilder content: () -> Content) {
self.offsetChanged = offsetChanged
self.content = content()
}
var body: some View {
List {
GeometryReader { geometry in
Color.clear.preference(key: ScrollOffsetPreferenceKey.self, value: geometry.frame(in: .named("ListView")).origin)
}
.frame(width: 0, height: 0)
content
.offset(y: -10)
}
.coordinateSpace(name: "ListView")
.onPreferenceChange(ScrollOffsetPreferenceKey.self, perform: offsetChanged)
}
}
private struct ScrollOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGPoint = .zero
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) { }
}
Run Code Online (Sandbox Code Playgroud)
这是我的ContentView:
struct ContentView: View {
@State private var contentOffset = CGFloat(0)
@State private var offsetPositionValue: CGFloat = 0
@State private var isShyHeaderVisible = false
var body: some View {
NavigationView {
ZStack {
TrackableListView { offset in
withAnimation {
contentOffset = offset.y
}
} content: {
Text("\(contentOffset)")
}
.overlay(
ZStack {
HStack {
Text("Total points")
.foregroundColor(.white)
.lineLimit(1)
Spacer()
Text("20,000 pts")
.foregroundColor(.white)
.padding(.leading, 50)
}
.padding(.horizontal)
.padding(.vertical, 8)
.frame(width: UIScreen.main.bounds.width)
.background(Color.green)
.offset(y: contentOffset < 50 ? 0 : -5)
.opacity(contentOffset < 50 ? 1 : 0)
.transition(.move(edge: .top))
}
.frame(maxHeight: .infinity, alignment: .top)
)
}
.navigationTitle("Hello")
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarTitleDisplayMode(.inline)
.frame(maxHeight: .infinity, alignment: .top)
.background(AccountBackground())
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我的层次结构中的其他视图(可能由 SwiftUI 引入)可能会发送默认值,这就是为什么有时你会开始得到零。
我需要的是一种方法来确定何时使用或转发新值,以及何时忽略它。
为此,我必须将我的值设置为可选 GCPoint,默认值为零,然后在使用 PreferenceKeys 时在您的reduce方法中执行以下操作:
if let nextValue = nextValue() {
value = nextValue
}
Run Code Online (Sandbox Code Playgroud)
然后确保您的 CGPoint 是可选值。