英文:
SwiftUI - Background color for view of tab item
问题
当我点击tabview
上的选项卡时,它会打开一个视图。我希望更改该视图的背景颜色。无论我做什么,它始终保持为白色。请查看下面的代码和屏幕截图:
注意:在下面的屏幕截图中,请忽略选项卡栏的位置。在我的实际应用程序中,它显示在底部,但由于代码太多,我只创建了一个示例应用程序。
如何将背景设置为灰色,并如何删除屏幕截图中突出显示的线/分隔线?
代码:
import SwiftUI
import Foundation
struct ContentView: View {
static let sliderHandleHeight: CGFloat = 15.0
static let radius: CGFloat = 16
@State private var tabViewPanelMinHeight: CGFloat = 250.0
@State private var tabViewPanelMaxHeight: CGFloat = 750.0
@State private var tabViewPanelCurrentHeight: CGFloat = 250.0
var body: some View {
GeometryReader { geometry in
VStack {
Image(systemName: "touchid").resizable().scaledToFit()
}
.onAppear {
tabViewPanelMinHeight = geometry.size.height * 0.25
tabViewPanelMaxHeight = geometry.size.height * 0.91
tabViewPanelCurrentHeight = tabViewPanelMinHeight
}
.overlay(alignment: .bottom) {
VStack {
RoundedRectangle(cornerRadius: 5.0)
.foregroundColor(.secondary)
.frame(width: 50, height: 7.0)
.frame(height: ContentView.sliderHandleHeight)
.padding(.top, 5.0)
.simultaneousGesture(tap)
BottomTabBarView()
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.cornerRadius(ContentView.radius)
.shadow(radius: 10)
.frame(width: geometry.size.width, height: tabViewPanelCurrentHeight + ContentView.sliderHandleHeight, alignment: .bottom)
}
}
}
var tap: some Gesture {
TapGesture(count: 1).onEnded {
tabViewPanelCurrentHeight = ((tabViewPanelCurrentHeight == tabViewPanelMinHeight) ? tabViewPanelMaxHeight : tabViewPanelMinHeight)
}
}
}
enum Tab: String, CaseIterable {
case none
case profile
case search
}
struct BottomTabBarView: View {
@State var activeTab = Tab.search
var body: some View {
TabView(selection: $activeTab) {
Group {
Text("Profile")
.tabItem {
Label("Profile", systemImage: "square.text.square.fill")
}
.tag(Tab.profile)
SearchExploreModalView()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
Text("Search")
}
.tag(Tab.search)
}
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.shadow(color: .black.opacity(0.3), radius: 0, x: 0, y: -0.5)
.onAppear {
let appearance = UITabBarAppearance()
UITabBar.appearance().scrollEdgeAppearance = appearance
}
}
}
struct SearchExploreModalView: View {
var body: some View {
VStack {
Text("Hello World")
}
.background(Color.gray)
}
}
屏幕截图:
英文:
Whenever I click on a tab on tabview, it opens a view. I wish to change the background color of that view. Doesn't matter what I do, it always stays white. Please look at the code and screenshot below:
Note: In the screenshot below, ignore positioning of the tab bar. In my actual app it shows at the bottom, but due to lot of code, I just created a sample app.
How can I set the background to gray and how can I remove the line/separator highlighted in the screenshot?
Code:
import SwiftUI
import Foundation
struct ContentView: View {
static let sliderHandleHeight: CGFloat = 15.0
static let radius: CGFloat = 16
@State private var tabViewPanelMinHeight: CGFloat = 250.0
@State private var tabViewPanelMaxHeight: CGFloat = 750.0
@State private var tabViewPanelCurrentHeight: CGFloat = 250.0
var body: some View {
GeometryReader { geometry in
VStack {
Image(systemName: "touchid").resizable().scaledToFit()
}
.onAppear {
tabViewPanelMinHeight = geometry.size.height * 0.25
tabViewPanelMaxHeight = geometry.size.height * 0.91
tabViewPanelCurrentHeight = tabViewPanelMinHeight
}
.overlay(alignment: .bottom) {
VStack {
RoundedRectangle(cornerRadius: 5.0)
.foregroundColor(.secondary)
.frame(width: 50, height: 7.0)
.frame(height: ContentView.sliderHandleHeight)
.padding(.top, 5.0)
.simultaneousGesture(tap)
BottomTabBarView()
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.cornerRadius(ContentView.radius)
.shadow(radius: 10)
.frame(width: geometry.size.width, height: tabViewPanelCurrentHeight + ContentView.sliderHandleHeight, alignment: .bottom)
}
}
}
var tap: some Gesture {
TapGesture(count: 1).onEnded {
tabViewPanelCurrentHeight = ((tabViewPanelCurrentHeight == tabViewPanelMinHeight) ? tabViewPanelMaxHeight : tabViewPanelMinHeight)
}
}
}
enum Tab: String, CaseIterable {
case none
case profile
case search
}
struct BottomTabBarView: View {
@State var activeTab = Tab.search
var body: some View {
TabView(selection: $activeTab) {
Group {
Text("Profile")
.tabItem {
Label("Profile", systemImage: "square.text.square.fill")
}
.tag(Tab.profile)
SearchExploreModalView()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
Text("Search")
}
.tag(Tab.search)
}
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.shadow(color: .black.opacity(0.3), radius: 0, x: 0, y: -0.5)
.onAppear {
let appearance = UITabBarAppearance()
UITabBar.appearance().scrollEdgeAppearance = appearance
}
}
}
struct SearchExploreModalView: View {
var body: some View {
VStack {
Text("Hello World")
}
.background(Color.gray)
}
}
Screenshot:
答案1
得分: 1
要使灰色成为标签的整个背景,只需允许包含"Text"的"VStack"无限扩展:
struct SearchExploreModalView: View {
var body: some View {
VStack {
Text("Hello World")
}
// 在这里:
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.gray)
}
}
你看到的"line"是你添加到"TabView"的阴影的一部分:
.shadow(color: .black.opacity(0.3), radius: 0, x: 0, y: -0.5)
删除这行会移除这个线条。
如果你实际上想要标签的背景在"grabber"之后继续,可以使用"ZStack"代替"VStack":
ZStack(alignment: .top) {
BottomTabBarView()
RoundedRectangle(cornerRadius: 5.0)
.foregroundColor(.secondary)
.frame(width: 50, height: 7)
.frame(height: ContentView.sliderHandleHeight)
.padding(.top, 5.0)
.simultaneousGesture(tap)
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.cornerRadius(ContentView.radius)
.shadow(radius: 10)
.frame(width: geometry.size.width, height: tabViewPanelCurrentHeight + ContentView.sliderHandleHeight, alignment: .bottom)
输出:
这可能会导致"grabber"与某些标签内容重叠。为了避免这种情况,在每个标签的开头添加一个高度为"ContentView.sliderHandleHeight"的"Spacer"。
话虽如此,你是想要重新创建"sheet"吗?
.sheet(isPresented: .constant(true)) {
BottomTabBarView()
.presentationDetents([.medium, .large])
}
英文:
To make the grey color the entire background of the tab, just allow the VStack
containing the Text
expand infinitely:
struct SearchExploreModalView: View {
var body: some View {
VStack {
Text("Hello World")
}
// here:
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.gray)
}
}
The "line" that you see is part of the shadow you added to TabView
:
.shadow(color: .black.opacity(0.3), radius: 0, x: 0, y: -0.5)
Removing this line removes the line.
If you actually want the background of the tab to continue beyond the "grabber", use a ZStack
instead of VStack
:
ZStack(alignment: .top) {
BottomTabBarView()
RoundedRectangle(cornerRadius: 5.0)
.foregroundColor(.secondary)
.frame(width: 50, height: 7)
.frame(height: ContentView.sliderHandleHeight)
.padding(.top, 5.0)
.simultaneousGesture(tap)
}
.background(Color(red: 0.98, green: 0.98, blue: 0.98).opacity(0.94))
.cornerRadius(ContentView.radius)
.shadow(radius: 10)
.frame(width: geometry.size.width, height: tabViewPanelCurrentHeight + ContentView.sliderHandleHeight, alignment: .bottom)
Output:
This might cause the "grabber" to overlap with some of the tabs' contents. To avoid this, you can add a Spacer
with height ContentView.sliderHandleHeight
at the start of each tab.
That said, are you trying to reinvent sheet
?
.sheet(isPresented: .constant(true)) {
BottomTabBarView()
.presentationDetents([.medium, .large])
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论