SwiftUI模块系列 - 已更新23篇
SwiftUI我的项目 - 已更新2个我的项目
往期Demo源码下载

效果图 - 自定tabbar动画成果

思路

  1. 应用Table先创立一个动态的tabbar
  2. 在自定义tabbar插入一个黄色的圆圈 设置偏移量是tabbar的按钮图标x的10偏移量左右
  3. 监听按钮点击去触发去偏移黄色圆圈的y值即可

代码

ContentView.swift

struct ContentView: View {    // MARK: Hiding Native One    // 暗藏Native One    init(){        UITabBar.appearance().isHidden = true    }            @State var currentTab : Tab = .home    var body: some View {        VStack(spacing:0){            TabView(selection:$currentTab) {                // MARK: Need to Apply BG For Each Tab View                // 须要为每个标签视图利用BG                Text("Home")                    .ApplyBG()                    .tag(Tab.home)                Text("Label")                    .ApplyBG()                    .tag(Tab.label)                Text("Position")                    .ApplyBG()                    .tag(Tab.position)                Text("Found")                    .ApplyBG()                    .tag(Tab.found)                Text("My")                    .ApplyBG()                    .tag(Tab.my)            }            CustomTabbar(currentTab: $currentTab)        }    }}struct ContentView_Previews: PreviewProvider {    static var previews: some View {        ContentView()    }}extension View{    func ApplyBG() -> some View {        // infinity 无穷的        self            .frame(maxWidth:.infinity,maxHeight: .infinity)            .background{                Color("BG")                .ignoresSafeArea()            }    }}

CustomTabbar.swift

struct CustomTabbar: View {    @Binding var currentTab : Tab        // MARK : To Animate Like Curve    // 动画曲线    @State var yOffset : CGFloat = 0    var body: some View {        GeometryReader{ proxy in            // 获取整体的宽度            let width = proxy.size.width            HStack(spacing:0) {                ForEach(Tab.allCases,id:\.rawValue){tab in                    Button {                        withAnimation(.easeInOut(duration: 0.2)) {                            currentTab = tab                            yOffset = -60                        }                        withAnimation(.easeInOut(duration: 0.1).delay(0.07)){                                                        yOffset = 0                        }                    } label: {                        Image(tab.rawValue)                            .renderingMode(.template)                            .resizable()                            .aspectRatio(contentMode: .fit)                            .frame(width:30,height: 30)                            .frame(maxWidth:.infinity)                            .foregroundColor(currentTab == tab ? Color("Purple"):.gray)                                                // MARK : Little Scaling Effect                        // 图标一个缩放动画成果                            .scaleEffect(currentTab == tab && yOffset != 0 ? 1.5 : 1)                    }                }            }            .frame(maxWidth:.infinity)            .background(alignment:.leading){                Circle()                    .fill(Color("Yellow"))                    .frame(width:25,height:25)                    .offset(x:10,y:yOffset)                    .offset(x:indicatorOffset(witdh: width))            }                    }        .frame(height:30)        .padding(.bottom,10)        .padding([.horizontal,.top])    }    // MARK: Indicator Offset    // 指示器偏移    func indicatorOffset(witdh : CGFloat) ->CGFloat {        let index = CGFloat(getIndex())        if index == 0 {return 0}                let buttonWidth = witdh / CGFloat(Tab.allCases.count)        return index * buttonWidth    }    func getIndex() -> Int {        switch currentTab {        case .home:            return 0        case .label:            return 1        case .position:            return 2        case .found:            return 3        case .my:            return 4        }    }}struct CustomTabbar_Previews: PreviewProvider {    static var previews: some View {        ContentView()    }}

Tab.swift

import SwiftUI// Mark : Enum For Tabs with Rawvlaue as Asset Image// 标记:Enum选项卡与Rawvlaue作为资产图像enum Tab : String ,CaseIterable {    case home = "Home"    case label = "Label"    case position = "Position"    case found = "Found"    case my = "My"}

demo源码

如需看源码,请点击下载!