如何为SwiftUI Picker View顶部(导航栏下方区域)设置背景色?
问题:为Picker所在页面的顶部安全区域添加背景色
我已给应用所有标签页和导航视图设置了统一的绿色头部样式,但Picker所在页面始终无法实现该效果。我希望顶部(从视图顶端到导航栏正下方的区域)的背景样式如下:
当前Picker视图的顶部为默认样式:
我尝试在Picker内部调用DrawNavBox()方法,但绿色块无法显示在视图顶部:
现有代码
首页货币绿色头部的实现代码
var body: some View { GeometryReader { g in VStack { DrawNavBox(g: g) // 绘制绿色头部 Text("Your home currency is:") .padding(.top, g.size.height * 0.10) Text("\(base.baseCur.baseCurrency) \(base.baseCur.baseCountry)") .font(.body) .fontWeight(.bold) .foregroundColor(.white) .padding(15) .background(Color("Dark Green")) .cornerRadius(20) .padding(.trailing, g.size.width * 0.19) .padding(.leading, g.size.width * 0.22) Form { Section(header: Text("Select Home Currency")) { Picker("Home Currency", selection: $gotBase) { DrawNavBox(g: g) ForEach(0 ..< currCountry.count, id: \.self) { item in VStack(alignment: .leading) { Text(currCountry[item]) .font(.subheadline) .padding(.leading, 25) HStack { Text(currSymbol[item]) Text(currName[item]) } .font(.caption) .padding(.leading, 25) } } } } } } .navigationBarTitle(Text("Home Currency"), displayMode: .inline) .navigationBarItems(trailing: Button(action: { // 切换基础货币 self.changeBaseCurrency() }) { Text ("Save").bold() } ) } }
设置导航栏区域绿色的DrawNavBox代码
struct DrawNavBox: View { var g: GeometryProxy var body: some View { ZStack (alignment: .top) { Color(.systemGreen) .frame(height: (g.safeAreaInsets.top), alignment: .top) .ignoresSafeArea() } } }
解决方案
问题出在你把DrawNavBox放在了VStack或Picker内部,而Form会占据视图空间并覆盖顶部区域。正确做法是将背景层放在最外层ZStack中,让它覆盖整个安全区域顶部,同时不影响其他内容布局:
- 用ZStack包裹整个内容,将
DrawNavBox作为底层背景 - 移除Picker内部和VStack里多余的
DrawNavBox调用
修改后的页面代码:
var body: some View { GeometryReader { g in ZStack { // 背景放在最底层,覆盖顶部安全区域 DrawNavBox(g: g) VStack { Text("Your home currency is:") .padding(.top, g.size.height * 0.10) Text("\(base.baseCur.baseCurrency) \(base.baseCur.baseCountry)") .font(.body) .fontWeight(.bold) .foregroundColor(.white) .padding(15) .background(Color("Dark Green")) .cornerRadius(20) .padding(.trailing, g.size.width * 0.19) .padding(.leading, g.size.width * 0.22) Form { Section(header: Text("Select Home Currency")) { Picker("Home Currency", selection: $gotBase) { ForEach(0 ..< currCountry.count, id: \.self) { item in VStack(alignment: .leading) { Text(currCountry[item]) .font(.subheadline) .padding(.leading, 25) HStack { Text(currSymbol[item]) Text(currName[item]) } .font(.caption) .padding(.leading, 25) } } } } } } } .navigationBarTitle(Text("Home Currency"), displayMode: .inline) .navigationBarItems(trailing: Button(action: { self.changeBaseCurrency() }) { Text ("Save").bold() } ) } }
另外可以优化DrawNavBox,无需依赖GeometryReader的safeAreaInsets,直接通过忽略安全区域来实现:
struct DrawNavBox: View { var body: some View { Color(.systemGreen) .ignoresSafeArea(.container, edges: .top) } }
优化后不需要在页面中传递GeometryProxy,代码更简洁。
内容的提问来源于stack exchange,提问作者Galen Smith
相关产品推荐
相关产品推荐

