You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS15.5(Xcode13.4.1)中SwiftUI TabBar选中项紫色背景框实现方法

问题描述

我正在iOS15.5(Xcode13.4.1)上开发SwiftUI应用,希望实现带有选中项紫色背景框的TabBar(目标样式:选中的Tab项被紫色圆角框包裹),但当前实现的TabBar无该紫色框(当前样式:选中项仅图标/文字变色,无背景框)。

当前实现代码:

import SwiftUI

var tabcolor = Color(red: 120/255, green: 57/255, blue: 62/255)

struct VistaMain: View {
    @EnvironmentObject var vm: ViewModel
    @State var seleccion : Int = 0
    
    var colorSeleccion: Color = Color(red: 73 / 255, green: 82 / 255, blue: 189 / 255)
    
    init(){
        UITabBar.appearance().barTintColor  = UIColor(red: 56/255, green: 57/255, blue: 62/255, alpha: 0)
        UITabBar.appearance().backgroundColor  = UIColor(red: 56/255, green: 57/255, blue: 62/255, alpha: 1)
    }
    
    var body: some View {
        //InicioView()
        Color(red: 48 / 255, green: 49 / 255, blue: 54 / 255)
            .ignoresSafeArea()
            .overlay(
        TabView(selection: $seleccion){
            NuevoExperimentoView()
                .tabItem{
                    Label("Nuevo exp", systemImage: "list.bullet.rectangle.portrait")//.background( frame(width: 30, height: 30))
                }
                .tag(0)
            NuevoExperimentoView()
                .tabItem{
                    Label("Nuevo exp", systemImage: "list.bullet.rectangle.portrait")
                }
                .tag(1)
            NuevoExperimentoView()
                .tabItem{
                    Label("Nuevo exp", systemImage: "list.bullet.rectangle.portrait")
                }
                .tag(2)

            VistaPerfilUsuario(usuarioCurrent: vm.usuariosArray[0], foto: UIImage(data: vm.usuariosArray[0].foto!)!).environmentObject(ViewModel())
                .tabItem{
                    Label("Perfil", systemImage: "person.circle.fill")
                }
                .tag(4)
        }
        )
    }
}

请问如何实现该紫色背景框?此功能在该iOS版本是否可行?

解决方案

可行性说明

iOS15.5的原生SwiftUI TabView没有直接提供给选中Tab项添加背景框的API,无法通过UITabBar.appearance()配置实现该效果,需要通过自定义TabBar的方式来达成需求。

实现步骤

  1. 隐藏原生TabBar,改用自定义底部导航栏替代
  2. 统一管理Tab项数据,基于选中状态渲染紫色背景框
  3. 绑定选中状态,切换对应页面视图

完整代码示例

import SwiftUI

var tabcolor = Color(red: 120/255, green: 57/255, blue: 62/255)

struct VistaMain: View {
    @EnvironmentObject var vm: ViewModel
    @State var seleccion: Int = 0
    
    // 选中项紫色背景色
    let colorSeleccion: Color = Color(red: 73 / 255, green: 82 / 255, blue: 189 / 255)
    // TabBar背景色
    let tabBarBgColor: Color = Color(red: 56/255, green: 57/255, blue: 62/255)
    
    // 统一管理Tab项数据
    private let tabItems: [(title: String, icon: String, tag: Int)] = [
        ("Nuevo exp", "list.bullet.rectangle.portrait", 0),
        ("Nuevo exp", "list.bullet.rectangle.portrait", 1),
        ("Nuevo exp", "list.bullet.rectangle.portrait", 2),
        ("Perfil", "person.circle.fill", 4)
    ]
    
    var body: some View {
        ZStack(alignment: .bottom) {
            // 页面背景
            Color(red: 48 / 255, green: 49 / 255, blue: 54 / 255)
                .ignoresSafeArea()
            
            // 根据选中状态切换页面
            switch seleccion {
            case 0: NuevoExperimentoView()
            case 1: NuevoExperimentoView()
            case 2: NuevoExperimentoView()
            case 4: 
                VistaPerfilUsuario(usuarioCurrent: vm.usuariosArray[0], foto: UIImage(data: vm.usuariosArray[0].foto!)!)
                    .environmentObject(ViewModel())
            default: NuevoExperimentoView()
            }
            
            // 自定义TabBar
            HStack(spacing: 0) {
                ForEach(tabItems, id: \.tag) { item in
                    Button(action: {
                        seleccion = item.tag
                    }) {
                        VStack(spacing: 4) {
                            Image(systemName: item.icon)
                            Text(item.title)
                                .font(.caption)
                        }
                        .foregroundColor(seleccion == item.tag ? .white : .gray)
                        .padding(.vertical, 8)
                        .padding(.horizontal, 12)
                        // 选中时显示紫色背景框
                        .background(seleccion == item.tag ? colorSeleccion : Color.clear)
                        .cornerRadius(8)
                    }
                    .frame(maxWidth: .infinity)
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 8)
            .background(tabBarBgColor)
            .ignoresSafeArea(edges: .bottom)
        }
        .onAppear {
            // 隐藏原生TabBar
            UITabBar.appearance().isHidden = true
        }
    }
}

// 以下为编译所需的占位视图/模型
struct NuevoExperimentoView: View {
    var body: some View {
        Text("Nuevo Experimento")
    }
}

struct VistaPerfilUsuario: View {
    let usuarioCurrent: ViewModel.Usuario
    let foto: UIImage
    @EnvironmentObject var vm: ViewModel
    
    var body: some View {
        Text("Perfil")
    }
}

class ViewModel: ObservableObject {
    struct Usuario: Identifiable {
        let id = UUID()
        let foto: Data?
    }
    @Published var usuariosArray = [Usuario(foto: UIImage(systemName: "person")?.pngData())]
}

代码说明

  • 用tabItems数组统一管理Tab项的标题、图标和标签,便于后续维护修改
  • 通过ZStack将页面内容与自定义TabBar叠加,TabBar固定在底部
  • 每个Tab项是可点击的Button,点击时更新选中状态
  • 利用background修饰符根据选中状态动态显示紫色背景框,搭配cornerRadius实现圆角效果
  • 隐藏原生UITabBar,避免与自定义导航栏冲突

内容的提问来源于stack exchange,提问作者Dox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:35:13