如何在 SwiftUI 中为 navigationBarHidden 设置动画?
How to animate navigationBarHidden in SwiftUI?
struct ContentView: View {
@State var hideNavigationBar: Bool = false
var body: some View {
NavigationView {
ScrollView {
VStack {
Rectangle().fill(Color.red).frame(height: 50)
.onTapGesture(count: 1, perform: {
withAnimation {
self.hideNavigationBar.toggle()
}
})
VStack {
ForEach(1..<50) { index in
HStack {
Text("Sample Text")
Spacer()
}
}
}
}
}
.navigationBarTitle("Browse")
.navigationBarHidden(hideNavigationBar)
}
}
}
当您点击红色矩形时,它会将导航栏弹开。我以为 withAnimation{}
会解决这个问题,但事实并非如此。在 UIKit
你会做这样的事情 navigationController?.setNavigationBarHidden(true, animated: true)
.
在 xCode 12 beta 6 和 xCode 11.7
中测试
您可以尝试使用
.navigationBarHidden(hideNavigationBar).animation(.linear(duration: 0.5))
而不是 .navigationBarHidden(hideNavigationBar)
并将self.hideNavigationBar.toggle()
移出动画块。如果您使用上述方法隐藏带动画的导航栏,则不需要。
我仍在学习 SwiftUI 中的动画,但在这个阶段,我知道您必须为父视图设置动画。
所以你的代码会变成...
struct ContentView: View {
@State var hideNavigationBar: Bool = false
var body: some View {
NavigationView {
ScrollView {
VStack {
Rectangle().fill(Color.red).frame(height: 50)
.onTapGesture(count: 1) {
self.hideNavigationBar.toggle()
}
VStack {
ForEach(1..<50) { index in
HStack {
Text("Sample Text")
Spacer()
}
}
}
}
}
.navigationBarTitle("Browse")
.navigationBarHidden(hideNavigationBar)
.animation(.spring()) // for example
}
}
}
请注意,任何函数调用中的最后一个参数都可以放在一个闭包中。
所以...
.onTapGesture(count: 1, perform: {
self.hideNavigationBar.toggle()
})
可以成为...
.onTapGesture(count: 1) {
self.hideNavigationBar.toggle()
}
我个人认为语法更简单。
我认为,唯一的解决方案是在 SwiftUI 2 中使用位置函数
var body: some View {
GeometryReader { geometry in
NavigationView {
ZStack {
Color("background")
.ignoresSafeArea()
// ContentView
}
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading: logo, trailing: barButtonItems)
.toolbar {
ToolbarItem(placement: .principal) {
SearchBarButton(placeholder: LocalizedStringKey("home_vc.search_bar.placeholder"))
.opacity(isNavigationBarHidden ? 0 : 1)
.animation(.easeInOut(duration: data.duration))
}
}
}
.frame(height: geometry.size.height + (isNavigationBarHidden ? 70 : 0))
// This is the key ⬇
.position(x: geometry.size.width/2, y: geometry.size.height/2 - (isNavigationBarHidden ? 35 : 0))
.animation(.easeInOut(duration: 0.38))
.onTapGesture {
isNavigationBarHidden.toggle()
}
}
}
struct ContentView: View {
@State var hideNavigationBar: Bool = false
var body: some View {
NavigationView {
ScrollView {
VStack {
Rectangle().fill(Color.red).frame(height: 50)
.onTapGesture(count: 1, perform: {
withAnimation {
self.hideNavigationBar.toggle()
}
})
VStack {
ForEach(1..<50) { index in
HStack {
Text("Sample Text")
Spacer()
}
}
}
}
}
.navigationBarTitle("Browse")
.navigationBarHidden(hideNavigationBar)
}
}
}
当您点击红色矩形时,它会将导航栏弹开。我以为 withAnimation{}
会解决这个问题,但事实并非如此。在 UIKit
你会做这样的事情 navigationController?.setNavigationBarHidden(true, animated: true)
.
在 xCode 12 beta 6 和 xCode 11.7
中测试您可以尝试使用
.navigationBarHidden(hideNavigationBar).animation(.linear(duration: 0.5))
而不是 .navigationBarHidden(hideNavigationBar)
并将self.hideNavigationBar.toggle()
移出动画块。如果您使用上述方法隐藏带动画的导航栏,则不需要。
我仍在学习 SwiftUI 中的动画,但在这个阶段,我知道您必须为父视图设置动画。
所以你的代码会变成...
struct ContentView: View {
@State var hideNavigationBar: Bool = false
var body: some View {
NavigationView {
ScrollView {
VStack {
Rectangle().fill(Color.red).frame(height: 50)
.onTapGesture(count: 1) {
self.hideNavigationBar.toggle()
}
VStack {
ForEach(1..<50) { index in
HStack {
Text("Sample Text")
Spacer()
}
}
}
}
}
.navigationBarTitle("Browse")
.navigationBarHidden(hideNavigationBar)
.animation(.spring()) // for example
}
}
}
请注意,任何函数调用中的最后一个参数都可以放在一个闭包中。
所以...
.onTapGesture(count: 1, perform: {
self.hideNavigationBar.toggle()
})
可以成为...
.onTapGesture(count: 1) {
self.hideNavigationBar.toggle()
}
我个人认为语法更简单。
我认为,唯一的解决方案是在 SwiftUI 2 中使用位置函数
var body: some View {
GeometryReader { geometry in
NavigationView {
ZStack {
Color("background")
.ignoresSafeArea()
// ContentView
}
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading: logo, trailing: barButtonItems)
.toolbar {
ToolbarItem(placement: .principal) {
SearchBarButton(placeholder: LocalizedStringKey("home_vc.search_bar.placeholder"))
.opacity(isNavigationBarHidden ? 0 : 1)
.animation(.easeInOut(duration: data.duration))
}
}
}
.frame(height: geometry.size.height + (isNavigationBarHidden ? 70 : 0))
// This is the key ⬇
.position(x: geometry.size.width/2, y: geometry.size.height/2 - (isNavigationBarHidden ? 35 : 0))
.animation(.easeInOut(duration: 0.38))
.onTapGesture {
isNavigationBarHidden.toggle()
}
}
}