2

I would like to know what's the difference or why I have a different behavior with my transition animation when I use two different blocks of if statements and when I use if-else statement expecting the same behavior, here some examples:

  • The following code works fine and the transition animation behave as expected:
VStack {
   homeHeader
            
   columnTitles
            
    if !showPortfolio {
       allCoinsListView
          .transition(.move(edge: .leading))
    }

    if showPortfolio {
       portfolioListView
           .transition(.move(edge: .trailing))
    }
            
    Spacer(minLength: 0)
}
  • The transition animation doesn't behave as expected:
VStack {
  homeHeader
            
  columnTitles
            
  if !showPortfolio {
       allCoinsListView
         .transition(.move(edge: .leading))
   } else {
       portfolioListView
         .transition(.move(edge: .trailing))
   }
            
   Spacer(minLength: 0)
}

2 Answers2

3

This is the ViewBuilder specifics:

  1. in the first case it creates a view for each condition (so two views are present on screen, one in, one out with transition);
  2. in the second case it creates only one view (with replaceable content), so it does not work.
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • What if you used a `switch showPortfolio`? In that case, would you add the `.transition` in each child view or on the parent view? – aheze Aug 17 '22 at 16:46
  • Hi @aheze , is the same behavior if I use switch, the problem was that its how the UI builder handle the if internally, the same way for switch, so I solved it using the .transition .asymmetric modifiers to explicitly remove the other view even if is not added to the view. – Adrian Piedra Aug 22 '22 at 14:41
1

I found a solution for this issue. The difference likely has to do with how the SwiftUI Result Builder translates the if-else statement into buildIf, buildEither, etc vs. how the if-else statements are translated. See: https://jasonzurita.com/swiftui-if-statement/

If you explicitly define asymmetric transitions in the if-else statement:

VStack {
    homeHeader
    
    columnTitles
    
    if !showPortfolio {
        allCoinsListView
            .transition(.asymmetric(insertion: .move(edge: .leading),
                                    removal: .move(edge: .trailing)))
    } else {
        portfolioListView
            .transition(.asymmetric(insertion: .move(edge: .trailing),
                                    removal: .move(edge: .leading)))
    }
    
    Spacer(minLength: 0)
}

I found the answer to this issue thanks to this post: SwiftUI Switch Statement Transition Behavior is not as expected