Hero库转场异常:Present视图控制器无动画,Dismiss正常如何解决
Hey there! I’ve run into this exact issue with Hero before—dismiss animations working but present ones being MIA is usually a simple configuration oversight. Let’s walk through the most likely fixes:
1. Use Hero’s Present Method (Not System Default)
First off, make sure you’re calling Hero’s dedicated present method instead of UIKit’s default present(_:animated:completion:). Hero needs to hook into the transition process, and using the system method skips that entirely:
// ❌ Wrong: Uses UIKit's default present, skips Hero present(secondVC, animated: true, completion: nil) // ✅ Correct: Uses Hero's present to trigger animation hero.present(secondVC, animated: true, completion: nil)
2. Assign Hero Properties to the Presented View Controller
Hero needs clear instructions on how to animate the transition. You can do this in two straightforward ways:
- Option A: Link views with a shared Hero ID
If you want a seamless transition between a specific view in your source VC and the presented VC’s view, set matchinghero.idvalues:// In your source VC (e.g., the button that triggers the present) triggerButton.hero.id = "transitionButton" // In your presented VC's viewDidLoad override func viewDidLoad() { super.viewDidLoad() view.hero.id = "transitionButton" } - Option B: Set a direct modal animation type
If you don’t need a view-linked transition, explicitly define the animation type for the presented VC:// In presented VC's viewDidLoad override func viewDidLoad() { super.viewDidLoad() view.hero.modalAnimationType = .zoom // Or .slide, .fade, .flip, etc. }
3. Check for Accidentally Disabled Hero Animations
Double-check that you haven’t toggled off Hero functionality somewhere:
- Ensure
view.hero.isEnabled = true(this is the default, but if you’ve overridden it in a base VC or global setting, reset it) - Avoid global settings like
Hero.shared.defaultAnimation = .noneunless you explicitly override it for the present transition
4. Handle Navigation Controllers (If Presenting One)
If you’re presenting a UINavigationController instead of a plain VC, apply the Hero properties to the navigation controller’s view instead of its root VC:
let navVC = UINavigationController(rootViewController: SecondViewController()) navVC.view.hero.modalAnimationType = .slide(direction: .right) hero.present(navVC, animated: true, completion: nil)
Quick Troubleshooting Tip
If none of the above works, add a quick print statement in your presented VC’s viewWillAppear to confirm Hero is active:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) print("Hero enabled for this VC: \(view.hero.isEnabled)") }
9 times out of 10, the issue is forgetting to use hero.present() or not setting the correct Hero animation properties on the presented side. Give these steps a shot!
内容的提问来源于stack exchange,提问作者Phoenix

