SwiftUI – Tab项视图的背景颜色

huangapple go评论72阅读模式
英文:

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:

SwiftUI – Tab项视图的背景颜色

答案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)

输出:

SwiftUI – Tab项视图的背景颜色

这可能会导致"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:

SwiftUI – Tab项视图的背景颜色

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])
}

huangapple
  • 本文由 发表于 2023年7月11日 13:11:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76658863.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定