Skip to content

Usage Guide

Luke Zhao edited this page Feb 5, 2017 · 26 revisions

Installation

Manual

Drag the Sources folder into your project. (Download)

Carthage

github "lkzhao/Hero"

CocoaPods

pod "Hero"

Swift Package Manager

Step 1

File > New > Project

Step 2

Create a Package.swift in root directory.

import PackageDescription

let package = Package(
    name: "NameOfYourPackage",
    dependencies: [
        .Package(url: "https://github.com/lkzhao/Hero")
    ]
)

Run swift package fetch

Step 3

Open the Xcode Project File. File > New > Target > Cocoa Touch Framework If you don't need Obj-C support remove the <target_name>.h files in the navigator.

Step 4

Go in Finder and drag & drop the sources from Packages/Hero/Sources into your project and add it to the Hero target.

Step 5

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.

Usage

Storyboard

  1. In the Identity Inspector, for every pair of source/destination views, give them the same HeroID attribute.
  2. For any other views that you would like to animate, specify the animation effects in Hero Modifier String attribute.
  3. Also in the Identity Inspector. Enable Hero Transition on your destination view controller.

In Code

  1. Before doing a transition, set the desired heroID & heroModifiers to source & destination views.
  2. 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.

Attributes

There are two important attributes to understand, heroID and 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.

Attribute Name Description
heroID Identifier for the view. Hero will automatically transition between views with the same heroID
heroModifiers Specifies the extra animations performed alongside the main transition.

HeroID

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

Use 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.

HeroModifierString

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.

Modifiers

Checkout HeroModifier.swift for definition details.

Basic Modifiers

Modifier Name Description
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

Advance Modifiers

Modifier Name Description
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 (linear, easeIn, easeOut, easeInOut, standard, deceleration, acceleration, sharp)
timingFunction(c1x, c1y, c2x, c2y) Custom cubic bezier timing function for the animation
spring(stiffness, damping) (iOS 9+) Use spring animation with custom stiffness & damping. The duration will be automatically calculated. Will be ignored if arc, curve, or duration is set.
useGlobalCoordinateSpace Force the view to use global coordinate space
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 HeroID. Not animatable.
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
ignoreSubviewModifiers Disables all heroModifiers for view's direct subviews
useScaleBasedSizeChange Force Hero use scale based size animation.
useOptimizedSnapshot Change snapshot type to OptimizedSnapshot, see Snapshot Types
useNormalSnapshot Change snapshot type to NormalSnapshot, see Snapshot Types
useLayerRenderSnapshot Change snapshot type to LayerRenderSnapshot, see Snapshot Types
useNoSnapshot Change snapshot type to NoSnapshot, see Snapshot Types

Modifiers Support for matched views

Some of the modifiers won't work with matched views(views with the same heroID). These are:

  • fade
  • scale
  • translate
  • rotate
  • transform
  • cascade

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.

Modifier Details

zPosition Modifier

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

Arc Modifier

When animating 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

The 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

The cascade modifier automatically applies increasing delay heroModifiers to a view's direct subviews.

Parameters Description
deltaDelay delay in between each animation
direction the cascade direction, can be topToBottom, bottomToTop, leftToRight, & rightToLeft, default topToBottom
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

The ignoreSubviewModifiers modifier disables all heroModifiers attributes for a view's direct subviews.

useScaleBasedSizeChange Modifier

Force Hero use scale based size animation. This will convert all .size modifier into .scale modifier. This is to help Hero animate layers that doesn't support bounds animation. Also gives better animation performance.

Snapshot Types

Hero creates snapshots of your animating views when performing animations. Use the following four modifiers to change how Hero take these snapshots.

useOptimizedSnapshot

 With this modifier, Hero will create snapshot optimized for different view type when animating.
 For custom views or views with masking, useOptimizedSnapshot might create snapshots
 that appear differently than the actual view.
 In that case, use .useNormalSnapshot or .useSlowRenderSnapshot to disable the optimization.

useNormalSnapshot

 Create snapshot using snapshotView(afterScreenUpdates:).

useLayerRenderSnapshot

 Create snapshot using layer.render(in: currentContext).
 This is slower than .useNormalSnapshot but gives more accurate snapshot for some views (eg. UIStackView).

useNoSnapshot

 Force Hero to not create any snapshot when animating this view. Hence Hero will animate on the view directly.
 This will mess up the view hierarchy. Therefore, view controllers have to rebuild its view structure after the transition finishes.

Coordinate Space

Global Coordinate Space (default before 0.1.3)

Animating views are not affected by parent views' attributes. Does not move with the parent view. I.e. They are being taken out of the view hierarchy once heroModifiers are applied. Use useGlobalCoordinateSpace modifier to force this behavior after 0.1.3.

Local Coordinate Space (default after 0.1.3)

Animating views moves along with its parent view. Note that when a view is matched, or when source or useGlobalCoordinateSpace modifiers are used, the view will go back to global coordinate space.

For the examples above, the following heroModifiers are applied.

greyView.heroModifiers = [.translate(y:100)]
blackView.heroModifiers = nil
redView.heroModifiers = [.translate(x:50)]

Navigation Helpers (dismiss, replace, unwind)

Hero provides some useful navigation extension methods on UIViewController. Use these alongside with pushViewController, presentViewController to navigate between view controllers.

func hero_dismissViewController()

 Dismiss the current view controller with animation. Will perform a navigationController.popViewController 
 if the current view controller is contained inside a navigationController.

func hero_replaceViewController(with:UIViewController)

 Replace the current view controller with another VC on the navigation/modal stack.

func hero_unwindToRootViewController()

 Unwind to the root view controller using Hero.

func hero_unwindToViewController(_ toViewController:)

 Unwind to a specific view controller using Hero.

func hero_unwindToViewController(withSelector: Selector)

 Unwind to a view controller that responds to the given selector using Hero.

func hero_unwindToViewController(withClass: AnyClass)

 Unwind to a view controller with given class using Hero.

func hero_unwindToViewController(withMatchBlock: (UIViewController) -> Bool)

 Unwind to a view controller that the match block returns true on.

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.

Clone this wiki locally