不得不说,在SwiftUI中,Preference这项技术实在是太神奇了,这也是我为什么写这么多与其相关文章的原因,它的原理是如此的简单,但加上我们的想象力,它却又无所不能。
在本篇文章中,我们将再次基于此技术,来实现一个最常用的功能,如下图所示:
SwiftUI为ScrollView提供的功能非常有限,以至于在UIKit中很容易实现的功能,在SwiftUI中,却变得毫无头绪,本例的核心思想非常简单,看下图就可明白:
核心思想就是,计算MovingView和FixedView两者之间的y的差,从而得到offset。
其中,FixedPositionView的代码如下:
/// 位置固定不变的view
struct FixedPositionView: View {
var body: some View {
GeometryReader {
proxy in
Color
.clear
.preference(key: MCRefreshablePreferenceTypes.MCRefreshablePreferenceKey.self,
value: [MCRefreshablePreferenceTypes.MCRefreshablePreferenceData(viewType: .fixedPositionView, bounds: proxy.frame(in: .global))])
}
}
}
可以看出,我们通过.preference
为其绑定了一个MCRefreshablePreferenceData类型的数据,最重要的目的是保存该view的bounds。那么同理,MovingPositionView的代码如下:
/// 位置随着滑动变化的view,高度为0
struct MovingPositionView: View {
var body: some View {
GeometryReader {
proxy in
Color
.clear
.preference(key: MCRefreshablePreferenceTypes.MCRefreshablePreferenceKey.self,