I'm trying to solve the iOS 15's warning:
'animation' was deprecated in iOS 15.0: Use withAnimation or animation(_:value:) instead.
in a view that appears on top of screen that looks like push notification alert (or what so called snack bar), but the view loses animation effect when I use any Equatable
value in the value
parameter, the code for this view is as follows (you can copy & paste it as is to try it out):
import Foundation
import SwiftUI
struct ContentView: View {
@State private var showSnackBar = false
var body: some View {
ZStack {
Color.gray
Text("Show Me")
.padding()
.onTapGesture {
showSnackBar = true
}
EmptyView()
.snackBar(title: "this is a test message", show: $showSnackBar)
.offset(x: 0, y: 50)
}
.edgesIgnoringSafeArea(.all)
}
}
struct SnackBarModifier: ViewModifier {
var title: String
@Binding var show: Bool
@State var task: DispatchWorkItem?
func body(content: Content) -> some View {
ZStack {
if self.show {
VStack {
HStack {
Text(title)
Spacer()
}
.foregroundColor(.white)
.padding(12)
.background(Color.orange)
.cornerRadius(8)
Spacer()
}
.frame(maxWidth: UIScreen.main.bounds.width - 40)
.animation(.easeInOut(duration: 0.7), value: ...) //<---- this is where I should use the value in order to solve iOS 15 animation deprecation warning
.transition(AnyTransition.move(edge: .top)
.combined(with: .opacity))
.onTapGesture {
withAnimation {
self.show = false
}
}
.onAppear {
self.task = DispatchWorkItem {
withAnimation {
self.show = false
}
}
// Auto dismiss after 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() 2, execute: self.task!)
}
.onDisappear {
self.task?.cancel()
}
}
content
}
}
}
extension View {
func snackBar(title: String, show: Binding<Bool>) -> some View {
self.modifier(SnackBarModifier(title: title, show: show))
}
}
I tried to use a separate boolean state var that is toggled when the self.show
is set to true but to no avail, how can I animate the appearance of this snack bar view using easeInOut(duration:)
animation using iOS 15's animation style ?
CodePudding user response:
Put animation modifier on top ZStack
container, like
struct SnackBarModifier: ViewModifier {
var title: String
@Binding var show: Bool
@State var task: DispatchWorkItem?
func body(content: Content) -> some View {
ZStack {
if self.show {
// other content ...
}
content
}
.animation(.easeInOut(duration: 0.7), value: show) // << here !!
}
}
Tested with Xcode 13.2 / iOS 15.2