0.3 C
New York
Sunday, February 23, 2025

ios – SwiftUI’s transition animation doesn’t run for the primary time


I’m having a little bit of an issue with SwiftUI’s transition animation.
I’m following a tutorias of the e book “Grasp SwiftUI”. The tutorial creates a tinder like app that swipes pictures to the left and proper. In the event you swipe move a threshold than the picture is faraway from the View’s hieraquie. The removam of the picture trigers a transition animation. The issue is that after I take away the primary imagem the animation does not happen, however from the second picture the animation runs simply high quality.
And if I decelerate animations within the simulator the animation runs usually the primary time. I do not know what is occurring.

Right here you possibly can see that after I drag than launch the picture it disappears with out animation. I do the identical to the next imagens and the animation runs usually:

enter image description here

And right here I slowed down animation on the simulator. You may see that the primary animation runs usually when animations are slowed:

enter image description here

Right here is the code that I’m utilizing:

//
//  ContentView.swift
//  SwiftUITinderTrip
//
//  Created by Simon Ng on 24/8/2020.
//

import SwiftUI

struct ContentView: View {
    
    @GestureState non-public var dragState: DragState = .inactive
    @State non-public var zIndexCounter: Double = 1_000_000_000.0
    @State non-public var lastIndex: Int = 1
    @State non-public var cardView: [CardView] = Array(journeys[0.. self.dragThreshold {
                                        self.removalTransition = .trailingBottom
                                    }
                                }
                                .onEnded { value in
                                    guard case .second(true, let drag?) = value,
                                          drag.translation.width < -dragThreshold || drag.translation.width > dragThreshold
                                    else {
                                        return
                                    }
                                    
                                    moveCard()
                                }
                        )
                }
            }
            
            Spacer(minLength: 20)
            
            BottomBar { } likeAction: { } bookItNowAction: { }
                .opacity(dragState.isDragging ? 0.0 : 1.0)
                .animation(.default)
        }
    }
    
    private func isTopCard(_ trip: CardView) -> Bool {
        guard let index = cardView.firstIndex(where: { $0.id == trip.id }) else { return false }
        return index == 0
    }
    
    private func zIndex(for trip: CardView) -> Double {
        let idx = isTopCard(trip) ? zIndexCounter : zIndexCounter - 1
        return idx
    }
    
    private func offset(for trip: CardView) -> CGSize {
        return isTopCard(trip)
            ? CGSize(width: dragState.tranlation.width, height: dragState.tranlation.height)
            : .zero
    }
    
    private func scaleEffect(for trip: CardView) -> CGFloat {
        if isTopCard(trip) {
            return dragState.isDragging ? 0.95 : 1.0
        }
        
        return 1.0
    }
    
    private func rotationEffect(for trip: CardView) -> Angle {
        return isTopCard(trip) ? .degrees(Double(dragState.tranlation.width / 10)) : .zero
    }
    
    private func opacity(for trip: CardView, withXMark isXMark: Bool) -> Double {
        if isTopCard(trip) {
            if isXMark {
                return dragState.tranlation.width < -dragThreshold ? 1.0 : 0
            }
            return dragState.tranlation.width > dragThreshold ? 1.0 : 0
        }
        
        return 0
    }
    
    private func moveCard() {
        cardView.removeFirst()
        lastIndex += 1
        zIndexCounter -= 1
        cardView.append(CardView(trip: trips[lastIndex % trips.count]))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

enum DragState {
    case inactive
    case urgent
    case dragging(translation: CGSize)
    
    var tranlation: CGSize {
        change self {
        case .inactive, .urgent:
            return .zero
        case let .dragging(translation):
            return translation
        }
    }
    
    var isDragging: Bool {
        change self {
        case .dragging:
            return true
        case .urgent, .inactive:
            return false
        }
    }
    
    var isPressing: Bool {
        change self {
        case .dragging, .urgent:
            return true
        case .inactive:
            return false
        }
    }
}

extension AnyTransition {
    static var trailingBottom: AnyTransition {
        AnyTransition.uneven(
            insertion: .identification,
            elimination: AnyTransition
                .transfer(edge: .trailing)
                .mixed(with: .transfer(edge: .backside))
        )
    }
    
    static var leadingBottom: AnyTransition {
        AnyTransition.uneven(
            insertion: .identification,
            elimination: AnyTransition
                .transfer(edge: .main)
                .mixed(with: .transfer(edge: .backside))
        )
    }
}

Any sugestion?
Thanks

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles