skip to Main Content

I am working on a slide in / out effect with opacity change that is achieved through following SwiftUI transition

VStack {

}
.transition(
  .asymmetric(
    insertion: .opacity
      .combined(with: .offset(x: 50)),
    removal: .opacity
      .combined(with: .offset(x: -50))
  )
)

In addition to opacity change and offset I would like to "blur in" the view on insertion and "blur out" the view in removal step. Unfortunately it looks like SwiftUI doesn’t offer .blur transition to combine with here, so I wanted to ask if it is possible to add these kinds of custom transitions somehow and combine with them?

2

Answers


  1. import SwiftUI
    
    struct BlurAnimationModifier: AnimatableModifier {
        
        var blur: Double
    
        var animatableData: Double {
            get { blur }
            set { blur = newValue }
        }
        
        func body(content: Content) -> some View {
            content
                .blur(radius: self.animatableData)
        }
    }
    
    
    
    extension AnyTransition {
        static var blur: AnyTransition {
            get {
                AnyTransition.modifier(
                    active: BlurAnimationModifier(blur: 5.0),
                    identity: BlurAnimationModifier(blur: 0.0)
                )
            }
        }
    }
    
    

    Then use it as follows:

    .transition(
        .asymmetric(
            insertion: .opacity
                .combined(with: .offset(x: 50)),
            removal: .opacity
                .combined(with: .offset(x: -50))
        ).combined(with: .blur)
    )
    
    Login or Signup to reply.
  2. 💡 I’m using a simpler animation since it’s identical to the one you’ve provided

    Method 1: Apply Modifier To A Conditional View

    Wrap the conditional view in a group and apply the blur based on the conditions like:

    Group { // 👈 Wrap the condition
        if showDetails {
            Text("This is the label")
                .transition(.opacity.combined(with: .offset(x: -50)))
        }
    }
    .blur(radius: showDetails ? 0 : 10) // 👈 Use the modifier on the group
    

    Demo

    Demo


    Method 2: Custom Transition

    You can create a custom transition using a custom AnimatableModifier.

    @Baffo rasta has mentioned this method before I have time to complete my answer and should have the credit, but here is mine which is some sort of refactored version of his:

    struct Blur: AnimatableModifier {
        init(radius: Double = 0) { animatableData = radius }
        var animatableData: Double
    
        func body(content: Content) -> some View {
            content.blur(radius: animatableData)
        }
    }
    
    extension AnyTransition {
        static var blur: AnyTransition {
            AnyTransition.modifier(active: Blur(radius: 10.0), identity: .init())
        }
    }
    

    Usage:

    .opacity
        .combined(with: .offset(x: -50))
        .combined(with: .blur) // 👈 Combine with other transitions
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search