Sliding One Swiftui View Out from Underneath Another

Animate a view from the side in SwiftUI

You can use a .transition() modifier on the circle, and the .blur() modifier on the other views that are not the circle, combined with .animation().

Also, on the views that are "not circle", you need to add another modifier: .allowsHitTesting(), to avoid having the user interacting with the views that are blurred.

Remember that, when you trigger someState, you must use the .withAnimation() closure, otherwise the circle will not slide in.

Here's how the code looks like (I added some things on the ZStack just to provide an example). I also made the someState variable a boolean for convenience in the example, but in your case you can just check for the enum.

CircleView

struct CircleView: View {
@Binding var someState: Bool
var body: some View {
Circle()
.foregroundColor(.red)
.overlay(Text("All is blur"))
.onTapGesture {
someState.toggle()
}

// These modifiers are necessary to animate the circle
.transition(.move(edge: .trailing))
.animation(.easeInOut, value: someState)
}
}

Another view

    @State private var someState = false
var body: some View {
GeometryReader { geo in
ZStack {
VStack {
Button {

// Without this closure, the circle does not slide in
withAnimation {
someState.toggle()
}
} label: {
Text("Show circle")
}
.padding()

Spacer()

Text("Bottom")
.padding()
}

// This modifier blurs the view that is not the circle
.blur(radius: someState ? 5 : 0)

// This modifier animates the blur effect
.animation(.easeInOut, value: someState)

// This is necessary to block the view from accepting user taps
// when the circle is showing
.allowsHitTesting(!someState)

if someState {
CircleView(someState: $someState)

// Stop the circle half-way
.offset(x: UIScreen.main.bounds.width / 2, y: 0)
}
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.ignoresSafeArea()
}
}

SwiftUI Animation Slide In and Out

Move conditional part into container and add animation to container, so it will animate content, like

var body: some View {
GeometryReader { geometry in

ZStack(alignment: .center) {
self.parentView()

VStack { // << here !!
if(self.isShowing == true){
VStack {
Text("This is a test view\n")
Button(action: {
self.isShowing.toggle()
}) {
Text("Close")
}
}
.frame(width: geometry.size.width, height: geometry.size.height)
.background(Color(UIColor.systemBackground))
.transition(.move(edge: self.isShowing ? .trailing : .leading))
}
}.animation(Animation.easeInOut(duration: 1.0)) // << here !!
}
}
}

How to support Slide In Out animation in SwiftUI?

Try this:

import SwiftUI

struct NotificationView: View {

@State private var showNotification = false

var body: some View {
ZStack {
SuccessNotification()
.offset(y: showNotification ? (-UIScreen.main.bounds.height / 3) : -UIScreen.main.bounds.height)
.animation(.interpolatingSpring(mass: 1.0, stiffness: 100.0, damping: 10, initialVelocity: 0), value: showNotification)
Button("Press me") { showNotification.toggle() }
}
}
}

struct NotificationView_Previews: PreviewProvider {
static var previews: some View {
NotificationView()
}
}

struct SuccessNotification: View {
var body: some View {
Text("Success")
.padding()
.foregroundColor(.white)
.frame(width: UIScreen.main.bounds.width - 10, height: 100)
.background(.green, in: RoundedRectangle(cornerRadius: 20))
}
}

'animation' was deprecated in iOS 15.0
So just use the @State that changes the animation as the value :

@State private var showNotification = false

.animation(.linear, value: showNotification)

SwiftUI: Animate offset to slide in from off screen

It can be done just with transition, like

demo

Tested with Xcode 13.3 / iOS 15.4

struct ContentView: View {

@State var isShowingBanner = true

var body: some View {
VStack {
VStack {
Spacer()

if isShowingBanner {
BannerView()
.transition(.move(edge: .bottom)) // << here !!
}
}
// >> empty container should not shrink !!
.frame(maxWidth: .infinity, maxHeight: .infinity)
.border(Color.black, width: 1.0)
.clipped()

Spacer()

Button("Toggle Banner") {
withAnimation {
isShowingBanner.toggle()
}
}
}
.padding()
}
}

SwiftUI: Pattern matching causes view to animate incorrectly

When the binding changes, the ChildView changes two things: Show "foo" which hadn't been there before, and change the offset of anything else to 0.
So animation will only work on what has been there before. i.e. "Bar".

But you can change the value of elements, that are already there:

struct ChildView: View {
@Binding var foo: String?

var body: some View {
HStack {
Text(foo ?? "")

Spacer()

Text("Bar")
}
.offset(y: foo != nil ? 0 : UIScreen.main.bounds.height)
}
}


Related Topics



Leave a reply



Submit