我正在尝试使用几何读取器获取滚动视图的位置。但是,我注意到它给了我不同的值,具体取决于我是否将其嵌入到 NavigationView 中。这是一个例子:
struct ContentView: View {
@State var headerLocation: CGFloat = 0
var body: some View {
ZStack(alignment: .top) {
Color.white
.ignoresSafeArea()
VStack(spacing: 0) {
ZStack {
Text("test.username")
.font(.custom("Helvetica Bold", size: 18))
}
.frame(height: 40)
.overlay(alignment: .bottom) {
GeometryReader { geo -> Color in
let minY = geo.frame(in: .global).minY
DispatchQueue.main.async {
if headerLocation == 0 {
headerLocation = minY
}
}
return Color.blue
}
.frame(width: 100, height: 1)
}
ScrollView {
VStack(spacing: 8) {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
GeometryReader { proxy -> Color in
let offset = proxy.frame(in: .global).minY
print("\(offset), \(headerLocation)")
return Color.green
}
.frame(width: 40, height: 1)
.padding(.top, 10)
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期运行。当应用程序启动时,它会设置屏幕顶部蓝色矩形的位置。如果我们滚动滚动视图,我们可以看到当我们将绿色矩形滚动到与蓝色矩形相同的位置时,数字是相等的。
现在使用下面的代码:
struct ContentView: View {
@State var headerLocation: CGFloat = 0
var body: some View {
NavigationView {
ZStack(alignment: .top) {
Color.white
.ignoresSafeArea()
VStack(spacing: 0) {
ZStack {
Text("test.username")
.font(.custom("Helvetica Bold", size: 18))
}
.frame(height: 40)
.overlay(alignment: .bottom) {
GeometryReader { geo -> Color in
let minY = geo.frame(in: .global).minY
DispatchQueue.main.async {
if headerLocation == 0 {
headerLocation = minY
}
}
return Color.blue
}
.frame(width: 100, height: 1)
}
ScrollView {
VStack(spacing: 8) {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
GeometryReader { proxy -> Color in
let offset = proxy.frame(in: .global).minY
print("\(offset), \(headerLocation)")
return Color.green
}
.frame(width: 40, height: 1)
.padding(.top, 10)
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut eu sem integer vitae. Pretium aenean pharetra magna ac. Vel pretium lectus quam id leo in vitae. Molestie nunc non blandit massa enim nec dui nunc mattis. Ornare quam viverra orci sagittis eu volutpat odio facilisis. Ultrices neque ornare aenean euismod elementum nisi quis. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit amet volutpat consequat mauris. Dapibus ultrices in iaculis nunc sed augue lacus viverra.")
}
}
}
}
.navigationTitle("")
.navigationBarTitleDisplayMode(.inline)
.navigationBarHidden(true)
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我们尝试做同样的事情时,我们可以看到,当绿色矩形与蓝色矩形位于同一位置时,它们具有不同的值。如何在保留导航视图的同时实现第一个代码块的功能?我已经尝试过不同的 NavigationBarDisplayModes 和 NavigationTitles
让我向您介绍.coordinateSpace()您可以在哪里选择要用于比较的视图GeometryReaders。简而言之,正如您所看到的,NavigationView与 中的值混淆GeometryReaders,因此由于它们都存在于 中ZStack,我们可以轻松地在那里比较它们。诀窍是告诉GeometryReaders使用什么视图。.coordinateSpace()我们通过放置在 上来做到这一点ZStack,然后,.global()我们使用 来代替 using .named()。我缩写了你的Text()以使其更短、更清晰。这是工作中的代码:
struct ContentView: View {
@State var headerLocation: CGFloat = 0
var body: some View {
NavigationView {
ZStack(alignment: .top) {
Color.white
.ignoresSafeArea()
VStack(spacing: 0) {
ZStack {
Text("test.username")
.font(.custom("Helvetica Bold", size: 18))
}
.frame(height: 40)
.overlay(alignment: .bottom) {
GeometryReader { geo -> Color in
//Use .named() instead of .global()
let minY = geo.frame(in: .named("ZStack")).minY
DispatchQueue.main.async {
if headerLocation == 0 {
headerLocation = minY
}
}
return Color.blue
}
.frame(width: 100, height: 1)
}
ScrollView {
VStack(spacing: 8) {
Text("Lorem.")
GeometryReader { proxy -> Color in
//Use .named() instead of .global()
let offset = proxy.frame(in: .named("ZStack")).minY
print("\(offset), \(headerLocation)")
return Color.green
}
.frame(width: 40, height: 1)
.padding(.top, 10)
Text("Lorem.")
Text("Lorem.")
Text("Lorem.")
Text("Lorem.")
}
}
}
}
// Put the .coordinateSpace here. The name can be any hashable value.
.coordinateSpace(name: "ZStack")
.navigationTitle("")
.navigationBarTitleDisplayMode(.inline)
.navigationBarHidden(true)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
354 次 |
| 最近记录: |