效果图 - 自定tabbar动画效果 思路SwiftUI小功能模块系列
0001、SwiftUI自定义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源码
如需看源码,请点击下载!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)