我想创建一个自定义的标题视图,它位于vstack内,在向上滚动时减小该自定义标题的高度。我遵循了这篇博客:https://www.bigmountainstudio.com/community/public/posts/13099-swiftui-geometryreader-sticky-header-when-scrolling-part-5
我与博客的不同之处在于将Image("Utah")替换为customView。
问题在于设置scrollView内部的VStack框架。如果我注释掉.frame修饰符,VStack将使用scrollView的整个空间,并尝试将其全部放置在顶部: 如果我尝试使用框架来设置滚动计算的偏移量,自定义标题视图将尝试使用所有空间,并忽略框架,如下所示: 有什么办法可以实现这里展示的行为吗? 抱歉内容很长,非常感谢您提供任何想法或其他方法来实现此滚动动画。我还尝试设置 .navigationBar() 但这只允许文本。也尝试了 .navigationBarItems(leading: customView) 但仅限于屏幕顶部的一半。
ScrollView {
ZStack(alignment: .top) {
// Bottom Layer
VStack(spacing: 20) {
ListContentView()
}
.padding(.horizontal, 20)
.padding(.top, 128)
// Top Layer (Header)
GeometryReader { gr in
VStack(alignment: .leading, spacing: 0) {
Spacer().frame(height: 32)
navigationHeader
.frame(height:
self.calculateHeight(minHeight: 44,
maxHeight: 128,
yOffset: gr.frame(in: .global).minY)
)
// sticky it to the top
.offset(y: gr.frame(in: .global).origin.y < 0 // Is it going up?
? abs(gr.frame(in: .global).origin.y) // Push it down!
: -gr.frame(in: .global).origin.y) // Push it up!
Spacer()
}
.border(.red)
}
}
}
.navigationBarHidden(true)
.background(.black)
}
func calculateHeight(minHeight: CGFloat, maxHeight: CGFloat, yOffset: CGFloat) -> CGFloat {
// If scrolling up, yOffset will be a negative number
if maxHeight + yOffset < minHeight {
// SCROLLING UP
// Never go smaller than our minimum height
return minHeight
}
// SCROLLING DOWN
return maxHeight
}
private var navigationHeader: some View {
Group {
Image("Back")
Text("Title")
.h2()
Spacer.withHeight(Spacing.C4)
Text("some subtitle text some subtitle text some subtitle text some subtitle text some subtitle text")
.subheader()
.fixedSize(horizontal: false, vertical: true)
}
}
问题在于设置scrollView内部的VStack框架。如果我注释掉.frame修饰符,VStack将使用scrollView的整个空间,并尝试将其全部放置在顶部: 如果我尝试使用框架来设置滚动计算的偏移量,自定义标题视图将尝试使用所有空间,并忽略框架,如下所示: 有什么办法可以实现这里展示的行为吗? 抱歉内容很长,非常感谢您提供任何想法或其他方法来实现此滚动动画。我还尝试设置 .navigationBar() 但这只允许文本。也尝试了 .navigationBarItems(leading: customView) 但仅限于屏幕顶部的一半。
.frame(maxHeight: .infinity)
,我会在答案中进行更正。 - ChrisR