Hero

repository·develop·Indexed 12 days ago

https://github.com/herotransitions/hero

A declarative iOS library for building view controller transitions using a 'Magic Move' style mechanism. It automatically animates views with matching heroID properties between source and destination view controllers and provides heroModifiers for custom animations like fade, scale, and translate. Supports Auto Layout, UICollectionView, UITableView, and Storyboards on iOS and tvOS 10.0+.

Tokens
2.2K
Snippets
10
Records
15
Agent score
48%

What's inside Hero

  1. How Hero's 'Magic Move' and heroID work

    develop

    Hero implements a concept similar to Keynote's 'Magic Move'. It automates transitions by pairing views between a starting and ending view controller. If two views share the same heroID, Hero automatically creates an animation that moves the view from its initial state to its final state.

    To use this, assign a unique string to the hero.id property of the views you want to animate across the transition.

    // In View Controller 1
    redView.hero.id = "ironMan"
    
    // In View Controller 2
    self.hero.isEnabled = true
    redView.hero.id = "ironMan"
  2. How to use heroModifiers for custom animations

    develop

    For views that do not have a matching heroID, or to add additional animation effects to existing transitions, you can use hero.modifiers. Modifiers allow you to specify how a view should behave during the transition (e.g., fading, scaling, or translating).

    Hero also supports a .cascade modifier, which can be applied to a parent view (like a UICollectionView) to trigger a sequence of animations for its subviews.

    // Applying modifiers to a single view
    whiteView.hero.modifiers = [.translate(y:100)]
    
    // Applying a cascade to a collection view and specific modifiers to cells
    collectionView.hero.modifiers = [.cascade]
    for cell in redCells {
        cell.hero.modifiers = [.fade, .scale(0.5)]
    }
  3. How Hero's Magic Move works

    develop

    Hero implements a concept similar to Keynote's Magic Move. It automatically transitions views between a source and destination view controller by matching their heroID properties.

    • Matched Views: If a view in the source and a view in the destination share the same heroID, Hero automatically animates the transition from the old state to the new state.
    • Unmatched Views: For views that do not have a matching heroID, you can define custom animations using the heroModifiers property. These animations run alongside the Magic Move animations.
    • Interactivity: All animations (both matched and unmatched) can be interactively controlled by user gestures.
    • Layout Compatibility: Hero works with Auto Layout, programmatic layout, UICollectionView, UITableView, UINavigationController, and UITabBarController without modifying their underlying layout objects.
    // Example of matching views via heroID
    // In View Controller 1
    redView.hero.id = "ironMan"
    
    // In View Controller 2
    redView.hero.id = "ironMan" // This view will transition from the redView in VC1
  4. Configure view transitions using heroID and heroModifiers

    develop

    You can control how specific views transition using the .hero property available on UIView and UIViewController.

    Matching Views

    Assign a unique string to the id property of a view in both the source and destination view controllers to trigger a Magic Move transition.

    Customizing Unmatched Views

    Use hero.modifiers to apply animations to views that don't have a matching ID or to add extra effects. Common modifiers include .fade, .scale, and .translate.

    Advanced Modifiers

    • .cascade: Used on a parent view (like a UICollectionView) to trigger a cascading animation for its children.
    • .useGlobalCoordinateSpace: Use this if a view is being covered by another matched view during transition due to coordinate space mismatches.
    // Simple Magic Move
    // View Controller 1
    redView.hero.id = "ironMan"
    
    // View Controller 2
    self.hero.isEnabled = true
    redView.hero.id = "ironMan"
    whiteView.hero.modifiers = [.translate(y:100)]
    
    // Advanced: Cascading animations in a collection view
    collectionView.hero.modifiers = [.cascade]
    for cell in redCells {
        cell.hero.modifiers = [.fade, .scale(0.5)]
    }
  5. Install Hero via Swift Package Manager

    develop

    Add Hero as a dependency in your Package.swift and specify it as a dependency for your target.

    // swift-tools-version:4.0
    import PackageDescription
    
    let package = Package(
        name: "MyPackage",
        dependencies: [
            .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.6.3"))
        ],
        targets: [
            .target(
                name: "MyPackage",
                dependencies: ["Hero"]
            )
        ]
    )
  6. Install Hero via Accio

    develop

    Add the package to your Package.swift and add Hero to your App target dependencies, then run accio update.

    // Package.swift
    .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.4.0")),
    
    // Target dependencies
    .target(
        name: "App",
        dependencies: [
            "Hero",
        ]
    ),
    .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.4.0")),
    
    .target(
        name: "App",
        dependencies: [
            "Hero",
        ]
    ),
  7. Troubleshoot Hero transitions

    develop

    Hero transition not working even with self.hero.isEnabled = true

    If you are performing a push/pop within a UINavigationController, ensure you have also enabled self.hero.isEnabled on the navigation controller itself.

    Views being covered during transition

    By default, matched views use global coordinate space while unmatched views use local coordinate space. If a view is being covered, apply the .useGlobalCoordinateSpace modifier to the view being covered.

    Push animation appearing alongside custom animation

    Hero provides a default push animation for navigation controllers. To disable it, set self.hero.navigationAnimationType to .fade or .none on the navigation controller.