Swift - Hero animation to dismiss View
Asked Answered
P

0

6

I am having trouble using the Hero Library to dismiss my ViewController with custom animation.

In the end I would like to have pretty much the exact same animation as in this video:

preferred dismiss animation

So far my dismiss animation looks like this:

my dismiss animation so far

I am having 3 major problems which I can not figure out:

1. When presenting/dismissing my ViewController there seems to be this white background behind my 2nd ViewController but I would like to just cover my first ViewController with the 2nd without any white views.

2. My image disappears after the user starts swiping down behind my views when instead it should not change its position (preferred dismiss animation) until the view actually dismisses. Same things goes for the add-Button in the bottom right corner.

3. Like in the preferred dismiss animation my the backgroundView(lightGray View in the 2nd video) should dismiss a bit fast then the other subviews. I tried using the cascade-modifier but couldn't get that effect.

This is my 2nd ViewController:

 override func viewDidLoad() {
    super.viewDidLoad()

    self.wishlistBackgroundView.hero.isEnabled = true
    self.wishlistBackgroundView.heroID = "wishlistView"

    self.wishlistBackgroundView.hero.modifiers = [.fade, .translate(CGPoint(x: 0, y: 800), z: 20)]

    // adding panGestureRecognizer
    panGR = UIPanGestureRecognizer(target: self,
              action: #selector(handlePan(gestureRecognizer:)))
    view.addGestureRecognizer(panGR)

    self.wishlistLabel.text = wishList.name
    self.wishlistImage.image = wishList.image
    self.theTableView.wishList = wishList.wishData
    self.theTableView.tableView.reloadData()


    view.addSubview(wishlistBackgroundView)
    view.addSubview(dismissWishlistViewButton)
    view.addSubview(menueButton)
    wishlistBackgroundView.addSubview(wishlistView)
    wishlistBackgroundView.addSubview(wishlistLabel)
    wishlistBackgroundView.addSubview(wishlistImage)
    wishlistView.addSubview(theTableView.tableView)
    wishlistView.addSubview(addWishButton)

    NSLayoutConstraint.activate([


        // constrain wishlistView
        wishlistBackgroundView.topAnchor.constraint(equalTo: view.topAnchor),
        wishlistBackgroundView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        wishlistBackgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        wishlistBackgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),


        wishlistView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 160.0),
        wishlistView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0),
        wishlistView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0),
        wishlistView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0),

        // constrain wishTableView
        theTableView.view.topAnchor.constraint(equalTo: wishlistView.topAnchor, constant: 60.0),
        theTableView.view.bottomAnchor.constraint(equalTo: wishlistView.bottomAnchor, constant: 0),
        theTableView.view.leadingAnchor.constraint(equalTo: wishlistView.safeAreaLayoutGuide.leadingAnchor, constant: 30.0),
        theTableView.view.trailingAnchor.constraint(equalTo: wishlistView.safeAreaLayoutGuide.trailingAnchor, constant: -30.0),

        // constrain dismissButton
        dismissWishlistViewButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
        dismissWishlistViewButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 23.0),

        // constrain menueButton
        menueButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
        menueButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -25.0),

        // constrain wishlistImage
        wishlistImage.topAnchor.constraint(equalTo: wishlistView.topAnchor, constant: -70),
        wishlistImage.leadingAnchor.constraint(equalTo: wishlistView.leadingAnchor, constant: 30),
        wishlistImage.widthAnchor.constraint(equalToConstant: 90),
        wishlistImage.heightAnchor.constraint(equalToConstant: 90),

        //constrain wishlistlabel
        wishlistLabel.topAnchor.constraint(equalTo: wishlistView.topAnchor, constant: -47),
        wishlistLabel.leadingAnchor.constraint(equalTo: wishlistImage.leadingAnchor, constant: 100),

        addWishButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
        addWishButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40),

    ])

    // set DeleteWishDelegate protocol for the table
    theTableView.deleteWishDelegate = self


}

// define a small helper function to add two CGPoints
func addCGPoints (left: CGPoint, right: CGPoint) -> CGPoint {
  return CGPoint(x: left.x + right.x, y: left.y + right.y)
}

// handle swqipe down gesture
@objc private func handlePan(gestureRecognizer:UIPanGestureRecognizer) {

    // calculate the progress based on how far the user moved
    let translation = panGR.translation(in: nil)
    let progress = translation.y / 2 / view.bounds.height

  switch panGR.state {
  case .began:
    // begin the transition as normal
    dismiss(animated: true, completion: nil)
  case .changed:

    Hero.shared.update(progress)

    // update views' position based on the translation
    let viewPosition = CGPoint(x: wishlistBackgroundView.center.x, y: translation.y + wishlistBackgroundView.center.y)

    Hero.shared.apply(modifiers: [.position(viewPosition)], to: self.wishlistBackgroundView)


  default:
    // finish or cancel the transition based on the progress and user's touch velocity
       if progress + panGR.velocity(in: nil).y / view.bounds.height > 0.3 {
         Hero.shared.finish()
       } else {
         Hero.shared.cancel()
       }
  }
}

I couldn't find any good tutorials on this nor anything on these topics on git. If anyone knows even one answer to any of the problems I am more than happy.

Technically these are 3 questions but they are quite related. If this is against SO rules, I am happy to ask them separately.

Paramount answered 10/1, 2020 at 15:41 Comment(6)
remove the fade modifier from your second view controller for white background.Pun
that didn't do anything :/Paramount
I just removed the .fade , if I remove the whole line the panGesture animation does not really work anymore. backgroundView does not move but instead just fadesParamount
Here is my git in case anyone would like to have a closer look at my project: github.com/chriskonnerth/WishlistParamount
Make sure that you have also enabled self.hero.isEnabled on the navigation controller if you are doing a push/pop inside the navigation controller.Cellar
I did that. It is not like the animation is not working at all. It is working. Just not the way I want it to. Another problem is that if I delete the wishlistBackgroundView.hero.modifiers there is a problem with dragging the view down. My wishlsitBackgroundView is not moving. But the animations do still workParamount

© 2022 - 2024 — McMap. All rights reserved.