SwiftUI模块系列 - 已更新23篇
SwiftUI我的项目 - 已更新2个我的项目
往期Demo源码下载
效果图 - 自定tabbar动画成果
思路
- 应用Table先创立一个动态的tabbar
- 在自定义tabbar插入一个黄色的圆圈 设置偏移量是tabbar的按钮图标x的10偏移量左右
- 监听按钮点击去触发去偏移黄色圆圈的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源码
如需看源码,请点击下载!