ios开发: 自定义tabview,页面可拖动切换

一,代码:


import SwiftUI

struct ContentView3: View {
    @State private var selectedTab = 0

    var body: some View {
        ZStack(alignment: .bottom) {
            // 使用 Page 样式实现左右滑动动画
            TabView(selection: $selectedTab) {
                HomeView2()
                    .tag(0)
                
                ListView2()
                    .tag(1)
                
                AboutView()
                    .tag(2)
            }
            // 核心设置:开启分页滑动模式
            // indexDisplayMode: .never 隐藏底部的原生小圆点
            .tabViewStyle(.page(indexDisplayMode: .never))
            .animation(.easeInOut, value: selectedTab) // 点击切换时的平滑动画
           
            // 自定义底部栏(因为 .page 模式下原生 TabBar 会消失)
            customTabBar
        }
        .ignoresSafeArea(.keyboard) // 避免键盘弹出影响布局
    }

    // 抽离出的自定义底部栏
    var customTabBar: some View {
        HStack {
            TabBarItem(title: "首页", icon: "house.fill", index: 0, selection: $selectedTab)
            Spacer()
            TabBarItem(title: "列表", icon: "list.bullet", index: 1, selection: $selectedTab)
            Spacer()
            TabBarItem(title: "关于", icon: "person.circle", index: 2, selection: $selectedTab)
        }
        .padding(.horizontal, 40)
        .frame(height: 100) // 这里调高高度
        .background(Color(.systemGray6))
        .shadow(color: .black.opacity(0.1), radius: 10, y: -5)
    }
}

// 按钮组件
struct TabBarItem: View {
    let title: String
    let icon: String
    let index: Int
    @Binding var selection: Int

    var body: some View {
        Button {
            withAnimation { selection = index }
        } label: {
            VStack(spacing: 4) {
                Image(systemName: icon).font(.system(size: 22))
                Text(title).font(.caption2)
            }
            .foregroundColor(selection == index ? .blue : .gray)
        }
    }
}

// --- 子页面定义 ---

struct HomeView2: View {
    var body: some View {
        VStack {
            Text("这是首页")
                .font(.headline)
            Image(systemName: "globe") // 使用系统图标
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 200, height: 200)
                .foregroundColor(.blue)
        }
    }
}

struct ListView2: View {
    var body: some View {
        VStack {
            Text("内容列表")
                .font(.headline)
            Image(systemName: "doc.text.magnifyingglass")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 200, height: 200)
                .foregroundColor(.green)
        }
    }
}

struct AboutView: View {
    var body: some View {
        VStack {
            Text("关于我们")
                .font(.headline)
            Image(systemName: "info.circle.fill")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 200, height: 200)
                .foregroundColor(.orange)
        }
    }
}

 

二,测试效果:

image

 

posted @ 2026-04-11 10:43  刘宏缔的架构森林  阅读(1)  评论(0)    收藏  举报