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 源码
如需看源码,请点击下载!