我正在为我的topCardView 和bottomView 使用滚动视图。当我每次尝试滚动时,都会出现帧尺寸无效的错误,或者有时会冻结。绑定首选项 SizePreferenceKey 尝试每帧更新多次。
我该如何解决这个问题?我非常感谢任何帮助。
我完成的代码:
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView(.vertical, showsIndicators: false, content: {
GeometryReader { reader in
topCardView
.offset(y: -reader.frame(in: .global).minY)
.frame(width: reader.size.width, height: reader.frame(in: .global).minY + 450)
}
.frame(height: 450)
VStack(spacing: 40) {
BottomView
}
.padding(.vertical, 32)
.padding(.horizontal, 16)
.background(
Color(red: 232/255, green: 230/255, blue: 225/255)
.cornerRadius(40)
)
.offset(y: -25)
})
}
@ViewBuilder
private var topCardView: some View {
ScrollView(.horizontal, showsIndicators: false) {
LazyHGrid(rows: Array(repeating: GridItem(), count: 1), spacing: 20) {
ForEach(0..<2) { _ in
RoundedRectangle(cornerRadius: 12)
.fill(Color(red: 248/255, green: 250/255, blue: 220/255))
.frame(width: 300, height: 377)
}
}
.padding(.horizontal, 20)
}
}
@ViewBuilder
private var BottomView: some View {
ForEach(0..<2) { _ in
VStack(alignment: .center) {
Text("Fastest Near You")
.bold()
.frame(width: UIScreen.main.bounds.width - 32 * 6, height: 35)
Text("Order your food here")
.frame(width: UIScreen.main.bounds.width - 32 * 4, height: 25)
LazyVGrid(columns: Array(repeating: GridItem(), count: 2), spacing: 12) {
ForEach(0..<4) { _ in
RoundedRectangle(cornerRadius: 12)
.fill(Color(red: 248/255, green: 250/255, blue: 220/255))
.frame(width: UIScreen.main.bounds.width / 2 - 24, height: 200)
}
}
.padding(.top, 20)
}
}
}
}
错误图片:
我在评论中问,为什么你要设置动态框架高度。您回复说,您想要创建视差效果。
我认为这可以在不使用动态框架高度的情况下实现:
GeometryReader
).frame(in: .scrollView)
来引用 ScrollView
ScrollView
的坐标空间命名为VStack
zIndex
应用于底视图,只是为了确保它始终显示在顶视图上方GeometryReader
可用于测量屏幕的尺寸,而不是使用 UIScreen.main
(已弃用)。所以也许可以尝试这样的事情:
struct ContentView: View {
var body: some View {
GeometryReader { outer in
let screenSize = outer.size
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 40) {
GeometryReader { reader in
let minY = reader.frame(in: .scrollView).minY
topCardView
.frame(maxHeight: .infinity)
.offset(y: -minY / 2)
}
.frame(height: screenSize.height / 2)
VStack(spacing: 40) {
bottomView(screenSize: screenSize)
}
.padding(.horizontal, 16)
.padding(.bottom, 40)
.background(
RoundedRectangle(cornerRadius: 40)
.fill(Color(red: 232/255, green: 230/255, blue: 225/255))
)
.zIndex(1)
}
}
}
}
@ViewBuilder
private var topCardView: some View {
// content as before
}
@ViewBuilder
private func bottomView(screenSize: CGSize) -> some View {
// content as before, but using screenSize instead of UIScreen.main.bounds
}
}