我有一个简单的看法:
var body: some View {
NavigationView {
ScrollView {
VStack {
ForEach(0..<2) { _ in
CardVew(for: cardData)
}
}
}
.navigationBarTitle("Testing", displayMode: .automatic)
}
}
但是您可以用任何东西替换CardView-故障仍然存在。 Glitch video有办法解决吗?
Xcode 12.0.1,Swift 5
最佳答案
将顶部填充设置为1会破坏至少两个主要方面:
当我不得不在正在处理的应用程序的所有屏幕上更改背景颜色时,我遇到了这些问题。
因此,我做了一些更多的挖掘和实验,并设法找到了解决该问题的不错的解决方案。
这是原始解决方案:
我们将ScrollView封装为2个几何读取器。
最重要的一点是尊重安全区域-我们需要这一点才能阅读安全区域插图
第二个是全屏显示。
我们将滚动 View 放入第二个几何读取器中-使其大小变为全屏。
然后,我们使用VStack通过应用安全区域填充来添加内容。
最后-我们拥有不会闪烁的滚动 View ,并且可以接受背景而不会破坏导航栏的大标题。
struct ContentView: View {
var body: some View {
NavigationView {
GeometryReader { geometryWithSafeArea in
GeometryReader { geometry in
ScrollView {
VStack {
Color.red.frame(width: 100, height: 100, alignment: .center)
ForEach(0..<5) { i in
Text("\(i)")
.frame(maxWidth: .infinity)
.background(Color.green)
Spacer()
}
Color.red.frame(width: 100, height: 100, alignment: .center)
}
.padding(.top, geometryWithSafeArea.safeAreaInsets.top)
.padding(.bottom, geometryWithSafeArea.safeAreaInsets.bottom)
.padding(.leading, geometryWithSafeArea.safeAreaInsets.leading)
.padding(.trailing, geometryWithSafeArea.safeAreaInsets.trailing)
}
.background(Color.yellow)
}
.edgesIgnoringSafeArea(.all)
}
.navigationBarTitle(Text("Example"))
}
}
}
优雅的解决方案由于该解决方案现在很清晰-让我们创建一个优雅的解决方案,只需替换填充修补程序即可将其重复使用并应用于任何现有ScrollView。
我们创建了ScrollView的扩展,该扩展声明了
fixFlickering
函数。逻辑基本上是,我们将接收器包装到几何读取器中,并使用安全区域填充将其内容包装到VStack中。
之所以使用ScrollView,是因为编译器错误地推断出嵌套滚动 View 的内容,该内容应与接收者相同。显式声明AnyView将使其接受包装的内容。
有2个重载:
.padding(.top, 1)
替换为.fixFlickering()
-就是这样。 extension ScrollView {
public func fixFlickering() -> some View {
return self.fixFlickering { (scrollView) in
return scrollView
}
}
public func fixFlickering<T: View>(@ViewBuilder configurator: @escaping (ScrollView<AnyView>) -> T) -> some View {
GeometryReader { geometryWithSafeArea in
GeometryReader { geometry in
configurator(
ScrollView<AnyView>(self.axes, showsIndicators: self.showsIndicators) {
AnyView(
VStack {
self.content
}
.padding(.top, geometryWithSafeArea.safeAreaInsets.top)
.padding(.bottom, geometryWithSafeArea.safeAreaInsets.bottom)
.padding(.leading, geometryWithSafeArea.safeAreaInsets.leading)
.padding(.trailing, geometryWithSafeArea.safeAreaInsets.trailing)
)
}
)
}
.edgesIgnoringSafeArea(.all)
}
}
}
例子1struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
VStack {
Color.red.frame(width: 100, height: 100, alignment: .center)
ForEach(0..<5) { i in
Text("\(i)")
.frame(maxWidth: .infinity)
.background(Color.green)
Spacer()
}
Color.red.frame(width: 100, height: 100, alignment: .center)
}
}
.fixFlickering { scrollView in
scrollView
.background(Color.yellow)
}
.navigationBarTitle(Text("Example"))
}
}
}
例子2struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
VStack {
Color.red.frame(width: 100, height: 100, alignment: .center)
ForEach(0..<5) { i in
Text("\(i)")
.frame(maxWidth: .infinity)
.background(Color.green)
Spacer()
}
Color.red.frame(width: 100, height: 100, alignment: .center)
}
}
.fixFlickering()
.navigationBarTitle(Text("Example"))
}
}
}
关于swift - ScrollView + NavigationView动画故障SwiftUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64280447/