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:
So far my dismiss animation looks like this:
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.
.fade
, if I remove the whole line the panGesture animation does not really work anymore.backgroundView
does not move but instead just fades – ParamountwishlistBackgroundView.hero.modifiers
there is a problem with dragging the view down. MywishlsitBackgroundView
is not moving. But the animations do still work – Paramount