我一直在寻找一种方法来复制Airbnb和许多其他工具所做的滚动动画,其中视图的顶部折叠/隐藏在滚动上,并在用户再次开始向上滚动时立即重新出现。请注意,在滚动附加的图像时,“日期”和“访客”按钮如何透明显示。
下面我附上了一个简单的视图,我只是将其放在一起。我尝试过在滚动视图的内部和外部都包含要折叠的区域。我猜想它需要在scrollview之外,因为它将独立地动画到您在滚动区域内的位置。
import SwiftUI
struct HideScrollView: View {
var body: some View {
ScrollView {
HStack {
Text("Hide Me")
Spacer()
}.padding(.horizontal) .frame(height: 60) .background(Color.red) .foregroundColor(Color.white)
ForEach(0 ..< 20) { item in
VStack {
HStack {
Text("Content Items")
Spacer()
}.padding(.horizontal) .frame(height: 40)
}
}
}
}
}
答案 0 :(得分:2)
由于没有像didScroll之类的scrollView委托,因此有两种方法可以实现所需的结果。
#1您应该实现DragGesture手势,这不是首选方式,因为不会同时调用手势。
.simultaneousGesture(DragGesture().onChanged({ transition in
if transition.translation.height > 0{
withAnimation{
self.viewIsShown = true
}
} else {
withAnimation{
self.viewIsShown = false
}
}
})
)
#2首选方式:根据Martin's tutorial,您应将GeometryReader
内的ScrollView
作为第一个孩子,这使您有可能获得元素在{{1}中的确切位置},就像这样:
GeometryReader
添加符合PreferenceKey协议的偏好密钥:
ScrollView(.vertical, showsIndicators: false) {
GeometryReader { geometry in
Color.clear.preference(key: OffsetKey.self, value: geometry.frame(in:.global).minY).frame(height: 0)
}
//Your scrollable content here
}
读取在首选项键中设置的值,将struct OffsetKey: PreferenceKey {
static let defaultValue: CGFloat? = nil
static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
value = value ?? nextValue()
}
}
添加到ScrollView或其任何父视图中。
.onPreferenceChange(OffsetKey.self)
和@State
都应该有initialOffest
包装器。
offset
检查.onPreferenceChange(OffsetKey.self) {
if self.initialOffset == nil || self.initialOffset == 0 {
self.initialOffset = $0
//setting initialOffest when view first appeared.
}
self.offset = $0
}
和initialOffset
之间的差异将告诉您视图的滚动状态。如果offset
高于initialOffset
,则视图将向下滚动,并且您应隐藏所需的视图。
根据您所发布的代码,它应如下所示:
offset