Clone this wiki locally
Sources folder into your project. (Download)
Swift Package Manager
File > New > Project
Package.swift in root directory.
import PackageDescription let package = Package( name: "NameOfYourPackage", dependencies: [ .Package(url: "https://github.com/lkzhao/Hero") ] )
swift package fetch
Open the Xcode Project File. File > New > Target > Cocoa Touch Framework If you don't need Obj-C support remove the .h files in the navigator.
Go in Finder and drag & drop the sources from
Packages/Hero/Sources into your project and add it to the Hero target.
Link your Project to the Hero dependency. Select your main target and add the CocoaTouchFramework to the Linked Frameworks and Libraries in the General Tab.
- In the Identity Inspector, for every pair of source/destination views, give them the same
- For any other views that you would like to animate, specify the animation effects in
Hero Modifier Stringattribute.
- Also in the Identity Inspector. Enable Hero Transition on your destination view controller.
- Before doing a transition, set the desired
heroModifiersto source & destination views.
Enables Hero for the destination view controller
viewController.isHeroEnabled = true
For UINavigationController & UITabBarController, you will need to enabled Hero on the navigation controller instance or the tab bar controller instance.
There are two important attributes to understand,
heroModifiers. These are implemented as extensions(using associated objects) for
UIView. Therefore, after the Hero library is imported, every
UIView will have these two attributes.
||Identifier for the view. Hero will automatically transition between views with the same
||Specifies the extra animations performed alongside the main transition.|
heroID is the identifier for the view. When doing a transition between two view controllers,
Hero will search through all the subviews for both view controllers and matches views with the same
heroID. Whenever a pair is discovered,
Hero will automatically transit the views from source state to the destination state.
heroModifiers to specify animations alongside the main transition. Checkout HeroModifier.swift for available modifiers.
For example, to achieve the following effect, set the
heroModifiers to be
view.heroModifiers = [.fade, .translate(x:0, y:-250), .rotate(x:-1.6), .scale(1.5)]
Note: For matched views, the target view's heroModifier will be used. The source view's heroModifier will be ignored. When dismissing, the target view is the presentingViewController's view and the source view is the presentedViewController's view.
This is a string value. It provides another way to set
heroModifiers. It can be accessed through the storyboard.
It must be in the following syntax:
modifier1() modifier2(parameter1) modifier3(parameter1, parameter2) ...
Parameters must be between a pair of parentheses, separated by a comma. Each modifier must be separated by a space. Not all modifiers are settable by this.
Checkout HeroModifier.swift for definition details.
|fade||Fade in or out when transitioning|
|position||Move to a position|
|size||Grow/shrink to a size|
|scale||Scale in 3d|
|rotate||Rotate in 3d|
|perspective||Set the transform's perspective|
|translate||Translate in 3d|
|delay(time)||Delay for the animation|
|duration(time)||Duration for the animation, if unspecified, the duration will be calculated based on the distance travelled|
|timingFunction(curveName)||Timing function for the animation (
|timingFunction(c1x, c1y, c2x, c2y)||Custom cubic bezier timing function for the animation|
(iOS 9+) Use spring animation with custom stiffness & damping. The duration will be automatically calculated. Will be ignored if
|zPosition(z)||The z axis height of the view during the animation phase. Not animatable.|
|zPositionIfMatched(z)||The z axis height of the view during the animation phase if being matched with another view by
|source(HeroID)||Transition from a view with given heroID|
|arc(intensity)||Make position animation follow a natural arc curve.|
|cascade(deltaDelay, direction, forceMatchedToWait)||Apply increasing delay to view's subview|
Modifiers Support for matched views
Some of the modifiers won't work with matched views(views with the same
heroID). These are:
NOTE: For other modifiers that works with matched views, the target view's modifiers will be used. the source view's modifiers will be ignored.
Hero cannot infer the correct zOrder of all the views. It currently always put destination views on top of the source views. Use the zPosition modifier to manually adjust the zOrder during the transition. See this issue for a reference use case: Transition "flashes" view temporarily disappearing
position, if arc is enabled. the view will follow a natural arc curve instead of going to the target position directly. See material design for more details.
The intensity parameter is a number that determine the curve's intensity. A value of 0 means no curve. A value of 1 means a natural downward curve. This value can be negative or above 1. Default is 1.
Use the debug plugin and enable Show Curves to see the actually arc curve objects follows.
source modifier allows a view to be transitioned from a view with the matching heroID.
See the Menu Example for how
source is used.
cascade modifier automatically applies increasing
delay heroModifiers to a view's direct subviews.
|deltaDelay||delay in between each animation|
|direction||the cascade direction, can be
|forceMatchedToWait||whether or not to delay matched views until all cascading animations have started, default false|
NOTE: matched views(views with the same
heroID) won't have the cascading effect. however, you can use the 3rd parameter to delay the start time of matched views until the last cascading animation have started. The matched views will animate simultaneously with the cascading views by default.
See the ListToGrid & ImageGallery Example for how
cascade is used.
ignoreSubviewModifiers modifier disables all
heroModifiers attributes for a view's direct subviews.
UINavigationController & UITabBarController
Hero also support transitions within a navigation controller or a tabbar controller. Just set the 'isHeroEnabled' attribute to true on the UINavigationController instance. Same for UITabBarController.