Search code examples
macosuser-interfaceswiftui

How do I show icons at the top of my tab panels


I have a right side panel in my window. Inside that right side panel are 4 tab panels. The icons for my tab controls (top tab not body) does not show.

struct RightPanelView: View {
    var body: some View {
        VStack {
            TabView {
            VStack{
                someView1( )
                someView2( )
            }
            .tabItem{ MyImage( "pencil" )}      // TODO These icons do not show up
            .background(Color.purple.opacity(0.2))

            VStack { someView3( dm )}
                .tabItem{ MyImage( "clock" )}
                .padding( 0 )

            VStack { someView4( dm )}
                .tabItem{ MyImage( "circle" )}
                .padding( 0 )
        }
    }
}

I know the System Names are correct since I have a row of buttons just above with the same icons. I was using Image() before and it has the same issue.

Here is what it looks like:

enter image description here

Edit-1

This is an example of FileMaker

enter image description here


Solution

  • Instead of using a TabView, you could create your own equivalent system, such as in this example code, adjust the looks as required.

    struct ContentView: View {
        var body: some View {
            NavigationSplitView(sidebar: {
                Text("sidebar")
            },
            detail: {
                RightPanelView()
            })
        }
    }
    
    enum TabSelection: String {
        case pencil, clock, circle
    }
    
    struct RightPanelView: View {
        @State private var selectedTab = TabSelection.pencil
        
        var body: some View {
            VStack {
                HStack {
                    Button { selectedTab = .pencil } label: { Image(systemName: "pencil") }
                        .border(selectedTab == .pencil ? .blue : .clear)
                    Button { selectedTab = .clock } label: { Image(systemName: "clock") }
                        .border(selectedTab == .clock ? .blue : .clear)
                    Button { selectedTab = .circle } label: { Image(systemName: "circle") }
                        .border(selectedTab == .circle ? .blue : .clear)
                }.padding(.top, 10)
                Spacer()
                switch selectedTab {
                    case .pencil: Text("someView0")
                    case .clock: Text("someView1")
                    case .circle: Text("someView2")
                }
                Spacer()
            }
        }
    }
    

    Or this:

    enum TabSelection: String, Identifiable, CaseIterable {
        case pencil, clock, circle
        var id: Int {
            switch self {
                case .pencil: return 1
                case .clock: return 2
                case .circle: return 3
            }
        }
    }
    
    struct RightPanelView: View {
        @State private var selectedTab = TabSelection.pencil
        
        var body: some View {
            VStack {
                HStack {
                    ForEach(TabSelection.allCases) { tab in
                        Button { selectedTab = tab } label: { Image(systemName: tab.rawValue) }
                            .overlay(selectedTab == tab ? RoundedRectangle(cornerRadius: 5)
                                .foregroundStyle(.blue).opacity(0.3) : nil)
                    }
                }.padding(.top, 10)
                Spacer()
                switch selectedTab {
                    case .pencil: Text("someView0")
                    case .clock: Text("someView1")
                    case .circle: Text("someView2")
                }
                Spacer()
            }
        }
    }