To help get you going...
First, no idea why you have your "deckPileImage" in a stack view, but assuming you have a reason for doing so...
a simple "card" view - bordered with rounded corners
class CardView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() {
        layer.cornerRadius = 16
        layer.masksToBounds = true
        layer.borderWidth = 1
        layer.borderColor = UIColor.black.cgColor
    }
}
a basic view controller - adds a "deck pile view" to a stack view, and a "card position view" as the destination for the new, animated cards.
class AnimCardVC: UIViewController {
    
    let deckStackView: UIStackView = UIStackView()
    let cardPositionView: UIView = UIView()
    let deckPileView: CardView = CardView()
    
    let cardSize: CGSize = CGSize(width: 80, height: 120)
    
    // card colors to cycle through
    let colors: [UIColor] = [
        .systemRed, .systemGreen, .systemBlue,
        .systemCyan, .systemOrange,
    ]
    var colorIDX: Int = 0
    
    // card position constraints to animate
    var animXAnchor: NSLayoutConstraint!
    var animYAnchor: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemBackground
        
        deckStackView.translatesAutoresizingMaskIntoConstraints = false
        deckPileView.translatesAutoresizingMaskIntoConstraints = false
        cardPositionView.translatesAutoresizingMaskIntoConstraints = false
        
        deckStackView.addArrangedSubview(deckPileView)
        view.addSubview(deckStackView)
        view.addSubview(cardPositionView)
        
        // always respect safe area
        let g = view.safeAreaLayoutGuide
        
        NSLayoutConstraint.activate([
            
            deckStackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            deckStackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            // we'll let the stack view subviews determine its size
            deckPileView.widthAnchor.constraint(equalToConstant: cardSize.width),
            deckPileView.heightAnchor.constraint(equalToConstant: cardSize.height),
            cardPositionView.topAnchor.constraint(equalTo: deckStackView.bottomAnchor, constant: 100.0),
            cardPositionView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            cardPositionView.widthAnchor.constraint(equalToConstant: cardSize.width + 2.0),
            cardPositionView.heightAnchor.constraint(equalToConstant: cardSize.height + 2.0),
            
        ])
        
        // outline the card holder view
        cardPositionView.backgroundColor = .systemYellow
        cardPositionView.layer.borderColor = UIColor.blue.cgColor
        cardPositionView.layer.borderWidth = 2
        
        // make the "deck card" gray to represent the deck
        deckPileView.backgroundColor = .lightGray
    }
    
    func animCard() {
        
        let card = CardView()
        card.backgroundColor = colors[colorIDX % colors.count]
        colorIDX += 1
        
        card.translatesAutoresizingMaskIntoConstraints = false
        
        card.widthAnchor.constraint(equalToConstant: cardSize.width).isActive = true
        card.heightAnchor.constraint(equalToConstant: cardSize.height).isActive = true
        
        view.addSubview(card)
        // center the new card on the deckCard
        animXAnchor = card.centerXAnchor.constraint(equalTo: deckPileView.centerXAnchor)
        animYAnchor = card.centerYAnchor.constraint(equalTo: deckPileView.centerYAnchor)
        
        // activate those constraints
        animXAnchor.isActive = true
        animYAnchor.isActive = true
        
        // run the animation *after* the card has been placed at its starting position
        DispatchQueue.main.async {
            // de-activate the current constraints
            self.animXAnchor.isActive = false
            self.animYAnchor.isActive = false
            // center the new card on the cardPositionView
            self.animXAnchor = card.centerXAnchor.constraint(equalTo: self.cardPositionView.centerXAnchor)
            self.animYAnchor = card.centerYAnchor.constraint(equalTo: self.cardPositionView.centerYAnchor)
            // re-activate those constraints
            self.animXAnchor.isActive = true
            self.animYAnchor.isActive = true
            // 1/2 second animation
            UIView.animate(withDuration: 0.5, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        animCard()
    }
    
}
It looks like this:

Each time you tap anywhere the code will add a new "card" and animate it from the "deck" view to the "card position" view.
 
  
 