效果图 - 自定tabbar动画效果
思路
代码
ContentView.swift
struct ContentView: View {
init(){
UITabBar.appearance().isHidden = true
}
@State var currentTab : Tab = .home
var body: some View {
VStack(spacing:0){
TabView(selection:$currentTab) {
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 {
self
.frame(maxWidth:.infinity,maxHeight: .infinity)
.background{
Color("BG")
.ignoresSafeArea()
}
}
}
CustomTabbar.swift
struct CustomTabbar: View {
@Binding var currentTab : Tab
@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)
.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])
}
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
enum Tab : String ,CaseIterable {
case home = "Home"
case label = "Label"
case position = "Position"
case found = "Found"
case my = "My"
}