如何在SwiftUI中为选中的TabView
标签栏项设置动画?
例如,为选定的项目添加.scaleEffect()
动画,.spring()
或如下所示:
这是我到目前为止尝试过的:
struct MyTabbedView: View {
@State var enlargeIt1 = false
@State var enlargeIt2 = true
var body: some View {
TabView {
Text("Item 1")
.onAppear {
self.enlargeIt1.toggle()
self.enlargeIt2.toggle()
}
.tabItem{
VStack{
Image(systemName: "music.note")
.font(self.enlargeIt1 ? .system(size: 30) : .system(size: 15) )
.animation(.interpolatingSpring(mass: 0.7, stiffness: 200, damping: 10, initialVelocity: 4))
Text("Music")
}
}.tag(1)
Text("Item 2")
.onAppear {
self.enlargeIt1.toggle()
self.enlargeIt2.toggle()
}
.tabItem{
VStack{
Image(systemName: "music.mic")
.font(self.enlargeIt2 ? .system(size: 30) : .system(size: 15) )
.animation(.interpolatingSpring(mass: 0.7, stiffness: 200, damping: 10, initialVelocity: 4))
Text("Mic")
}
}.tag(2)
}
}
}
结果是这样的:
我在名为 TestView 的单独视图中尝试了大约相同的代码:
struct TestView: View {
@State var enlargeIt1 : Bool = false
var body: some View {
VStack{
Image(systemName: "music.note")
.font(self.enlargeIt1 ? .system(size: 30) : .system(size: 15) )
.animation(.interpolatingSpring(mass: 0.7, stiffness: 200, damping: 10, initialVelocity: 4))
Text("Music")
}
.onTapGesture {
self.enlargeIt1.toggle()
}
}
}
这是结果:
我创建的TabView
不能给出相同的结果怎么了?
答案 0 :(得分:1)
有人创建了一个自定义TabView
,可能会对您有所帮助。我相信您可以对其进行修改以满足您的需求。
受此concept启发的SwiftUI的BottomBar组件
https://github.com/smartvipere75/bottombar-swiftui
import SwiftUI
import BottomBar_SwiftUI
let items: [BottomBarItem] = [
BottomBarItem(icon: "house.fill", title: "Home", color: .purple),
BottomBarItem(icon: "heart", title: "Likes", color: .pink),
BottomBarItem(icon: "magnifyingglass", title: "Search", color: .orange),
BottomBarItem(icon: "person.fill", title: "Profile", color: .blue)
]
struct BasicView: View {
let item: BottomBarItem
var detailText: String {
"\(item.title) Detail"
}
var followButton: some View {
Button(action: openTwitter) {
VStack {
Text("Developed by Bezhan Odinaev")
.font(.headline)
.color(item.color)
Text("@smartvipere75")
.font(.subheadline)
.foregroundColor(.gray)
}
}
}
var destination: some View {
Text(detailText)
.navigationBarTitle(Text(detailText))
}
var navigateButton: some View {
NavigationLink(destination: destination) {
ZStack {
Rectangle()
.fill(item.color)
.cornerRadius(8)
.frame(height: 52)
.padding(.horizontal)
Text("Navigate")
.font(.headline)
.foregroundColor(.white)
}
}
}
func openTwitter() {
guard let url = URL(string: "https://twitter.com/smartvipere75") else {
return
}
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
var body: some View {
VStack {
Spacer()
followButton
Spacer()
navigateButton
}
}
}
struct ContentView : View {
@State private var selectedIndex: Int = 0
var selectedItem: BottomBarItem {
items[selectedIndex]
}
var body: some View {
NavigationView {
VStack {
BasicView(item: selectedItem)
.navigationBarTitle(Text(selectedItem.title))
BottomBar(selectedIndex: $selectedIndex, items: items)
}
}
}
}
答案 1 :(得分:1)
这里是标准TabView
的可行方法(用于提供的代码快照)。
这个想法是使用可动画的修饰符来修饰使用过的SF图像的字体大小。
通过Xcode 11.4 / iOS 13.4测试
// Animating font size
struct AnimatableSFImage: AnimatableModifier {
var size: CGFloat
var animatableData: CGFloat {
get { size }
set { size = newValue }
}
func body(content: Self.Content) -> some View {
content
.font(.system(size: size))
}
}
// helper extension
extension Image {
func animatingSF(size: CGFloat) -> some View {
self.modifier(AnimatableSFImage(size: size))
}
}
// Modified test code snapshot
struct TestAnimatedTabBar: View {
@State var enlargeIt1 = false
@State var enlargeIt2 = true
var body: some View {
TabView {
Text("Item 1")
.onAppear {
self.enlargeIt1.toggle()
self.enlargeIt2.toggle()
}
.tabItem{
VStack{
Image(systemName: "music.note")
.animatingSF(size: self.enlargeIt1 ? 30 : 15 )
Text("Music")
}.animation(.interpolatingSpring(mass: 0.7,
stiffness: 200, damping: 10, initialVelocity: 4))
}.tag(1)
Text("Item 2")
.onAppear {
self.enlargeIt1.toggle()
self.enlargeIt2.toggle()
}
.tabItem{
VStack{
Image(systemName: "music.mic")
.animatingSF(size: self.enlargeIt2 ? 30 : 15 )
Text("Mic")
}.animation(.interpolatingSpring(mass: 0.7,
stiffness: 200, damping: 10, initialVelocity: 4))
}.tag(2)
}
}
}