如何在ZStack中设置背景图片且不破坏动画效果?
解决ScrollView边缘到边缘背景图随导航栏标题动画变形的问题
问题根源
你的代码中,GeometryReader嵌套在NavigationView内部,当导航栏标题从大标题切换到行内标题时,导航栏高度会动态变化,导致GeometryReader返回的可用区域尺寸改变,进而让图片的aspectRatio跟着调整,最终出现背景图变形的情况。
解决方案1:使用固定屏幕尺寸
直接获取整个屏幕的宽高比,让图片基于屏幕尺寸适配,不受导航栏变化影响:
struct Test: View { private let screenSize = UIScreen.main.bounds.size var body: some View { NavigationView { ScrollView { ZStack { Image("paperBG") .resizable() .aspectRatio(screenSize, contentMode: .fill) .edgesIgnoringSafeArea(.all) Text("hi") } } .navigationBarTitle("Title") .navigationBarTitleDisplayMode(.automatic) } } }
解决方案2:将图片设为ScrollView背景
把背景图片直接绑定到ScrollView的background修饰符,避免受ScrollView内部布局变化影响:
struct Test: View { var body: some View { NavigationView { ScrollView { Text("hi") .padding() } .background( Image("paperBG") .resizable() .aspectRatio(UIScreen.main.bounds.size, contentMode: .fill) .edgesIgnoringSafeArea(.all) ) .navigationBarTitle("Title") .navigationBarTitleDisplayMode(.automatic) } } }
解决方案3:外部嵌套GeometryReader
如果需要基于屏幕尺寸但不想直接调用UIScreen,可以把GeometryReader放在NavigationView外面,获取整个屏幕的固定尺寸:
struct Test: View { var body: some View { GeometryReader { screenGeometry in NavigationView { ScrollView { ZStack { Image("paperBG") .resizable() .aspectRatio(screenGeometry.size, contentMode: .fill) .edgesIgnoringSafeArea(.all) Text("hi") } } .navigationBarTitle("Title") .navigationBarTitleDisplayMode(.automatic) } } } }
内容的提问来源于stack exchange,提问作者erotsppa
相关产品推荐
相关产品推荐

