根据选择的选项卡更改 Tabview 颜色 -Swiftui

人气:659 发布:2022-10-16 标签: ios swiftui swift tabview uitabbar

问题描述

我想看看是否可以根据选择的选项卡项更改底部 tabview 的颜色.目前,我可以在 init 中使用以下代码清除 tabview 栏.

I am trying to see if I can make the color of the bottom tabview change depending on which tab item is selected. Currently I can make the tabview bar clear with the below code in the init.

let tabBar = UITabBar.appearance()
    init() {
        tabBar.barTintColor = UIColor.clear
        tabBar.backgroundImage = UIImage()
        tabBar.shadowImage = UIImage()
    }
 ...
 TabView(selection: $selectedTab) {
                FirstView()
                    .tabItem{
                        Text("First")
                    }
                SecondView()
                    .tabItem{
                        Text("Second")
                    }
    }
    .onAppear{
setTabViewBackground()
}

func setTabViewBackground() {
        if selectedTab != 0 {
            tabBar.barTintColor = UIColor.blue
        }
    }

尝试在主体重绘和 idk 时触发 func,如果它的这种声明式风格让我受益匪浅,但根本不改变 tabview 背景.

Tried to just fire the func when the body redraws and idk if its this declarative style that's getting the best of me but doesn't change the tabview background at all.

推荐答案

任何 .appearance 都会影响在外观本身之后创建的实例.所以解决方案是在外观配置改变后重新创建 TabView.

Any .appearance affects instances created after the appearance itself. So the solution is to re-create TabView after appearance configuration changed.

这是方法的演示.使用 Xcode 12/iOS 14 进行测试.

Here is a demo of approach. Tested with Xcode 12 / iOS 14.

struct DemoView: View {

    let tabBar = UITabBar.appearance()

    init() {
        tabBar.barTintColor = UIColor.red
    }

    @State private var selectedTab = 0    // preserves selected tab

    var body: some View {
        TabView(selection: $selectedTab) {
            Text("FirstView")
                .tabItem{
                    Text("First")
                }.tag(0)
            Text("SecondView")
                .tabItem{
                    Text("Second")
                }.tag(1)
        }
        .onAppear {
            setTabViewBackground()  // called, because `id` is below
        }
        .id(selectedTab)   // recreates entire above view with new tabbar
    }

    func setTabViewBackground() {
        tabBar.barTintColor = selectedTab != 0 ? .blue : .red
    }
}

659