Repository: HeroTransitions/Hero Branch: develop Commit: d7a72e13b034 Files: 355 Total size: 3.9 MB Directory structure: gitextract_d9vexhun/ ├── .codecov.yml ├── .editorconfig ├── .github/ │ ├── CODEOWNERS │ ├── FUNDING.yml │ ├── auto_assign.yml │ ├── issue_template.md │ ├── main.workflow │ ├── stale.yml │ └── workflows/ │ ├── build.yml │ ├── rebase.yml │ ├── swiftlint.yml │ └── test.yml ├── .gitignore ├── .jazzy.yaml ├── .makefiles/ │ ├── bundler.mk │ ├── docker-compose.mk │ ├── help.awk │ ├── ios.mk │ ├── ludicrous.mk │ └── virtualenv.mk ├── .swiftlint.yml ├── .travis.yml ├── CHANGELOG.md ├── DEVELOP.md ├── Dangerfile ├── Examples/ │ ├── AppStoreCardExample.swift │ ├── BuiltInTransitionExample.swift │ ├── ExampleBaseViewController.swift │ ├── MainViewController.swift │ ├── MatchExample.swift │ ├── MatchInCollectionExample.swift │ ├── Resources/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ ├── App Icon & Top Shelf Image.brandassets/ │ │ │ │ ├── App Icon - Large.imagestack/ │ │ │ │ │ ├── Back.imagestacklayer/ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Contents.json │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── Front.imagestacklayer/ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Middle.imagestacklayer/ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── App Icon - Small.imagestack/ │ │ │ │ │ ├── Back.imagestacklayer/ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Contents.json │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── Front.imagestacklayer/ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Middle.imagestacklayer/ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Contents.json │ │ │ │ ├── Contents.json │ │ │ │ ├── Top Shelf Image Wide.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── Top Shelf Image.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── AppleHomePage/ │ │ │ │ ├── Contents.json │ │ │ │ ├── iphone_alt_small_2x.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── macbookpro_portrait_small_2x.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── watch_alt_portrait_small_2x.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── CityGuide/ │ │ │ │ ├── Contents.json │ │ │ │ ├── cityGuide.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── montreal.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── toronto.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── vancouver.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Foods/ │ │ │ │ ├── Contents.json │ │ │ │ ├── Unsplash0.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash0_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash0_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash1.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash10.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash10_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash10_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash1_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash1_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash2.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash2_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash2_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash3.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash3_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash3_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash4.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash4_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash4_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash5.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash5_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash5_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash6.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash6_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash6_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash7.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash7_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash7_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash8.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash8_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash8_thumb.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash9.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Unsplash9_cell.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── Unsplash9_thumb.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── HeroLogo.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── Menu/ │ │ │ │ ├── Contents.json │ │ │ │ ├── ic_audiotrack_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_chat_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_format_quote_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_gif_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_insert_photo_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_link_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_menu_36pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_menu_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_text_fields_48pt.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── ic_videocam_48pt.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── MusicPlayer/ │ │ │ │ ├── Contents.json │ │ │ │ ├── album1.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_fast_forward.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_fast_rewind.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_pause_white.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_play_arrow_white.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── ic_repeat.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── ic_shuffle.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── bigbuckbunny.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ic_bug_report_48pt.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ic_close.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ic_code.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ic_input_48pt.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ic_keyboard_arrow_down.imageset/ │ │ │ │ └── Contents.json │ │ │ ├── ic_view_list.imageset/ │ │ │ │ └── Contents.json │ │ │ └── ic_view_module.imageset/ │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ └── LaunchScreen.storyboard │ │ ├── Info.plist │ │ └── UIKit+HeroExamples.swift │ └── SwiftUIMatchExample.swift ├── Gemfile ├── Hero.podspec ├── Hero.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata/ │ └── xcschemes/ │ ├── Hero (tvOS).xcscheme │ ├── Hero.xcscheme │ └── HeroExamples.xcscheme ├── Hero.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── LICENSE ├── LegacyExamples/ │ ├── Base.lproj/ │ │ └── Main.storyboard │ ├── Examples/ │ │ ├── AppleHomePage/ │ │ │ ├── AppleHomePage.storyboard │ │ │ └── AppleProductViewController.swift │ │ ├── Basic.storyboard │ │ ├── BuiltInTransition/ │ │ │ ├── AnimationSelectTableViewController.swift │ │ │ └── BuiltInTransitions.storyboard │ │ ├── CityGuide/ │ │ │ ├── City.swift │ │ │ ├── CityGuide.storyboard │ │ │ ├── CityGuideCell.swift │ │ │ ├── CityGuideViewController.swift │ │ │ └── CityViewController.swift │ │ ├── ImageGallery/ │ │ │ ├── ImageCells.swift │ │ │ ├── ImageGallery.storyboard │ │ │ ├── ImageGalleryCollectionViewController.swift │ │ │ ├── ImageLibrary.swift │ │ │ ├── ImageViewController.swift │ │ │ └── ImageViewer.storyboard │ │ ├── ListToGrid/ │ │ │ ├── GridCollectionViewController.swift │ │ │ ├── ListTableViewController.swift │ │ │ └── ListToGrid.storyboard │ │ ├── Menu/ │ │ │ ├── Menu.storyboard │ │ │ └── MenuViewController.swift │ │ ├── MusicPlayer.storyboard │ │ ├── Navigation/ │ │ │ ├── FirstViewController.swift │ │ │ └── Navigation.storyboard │ │ └── VideoPlayer/ │ │ ├── VideoPlayer.storyboard │ │ └── VideoPlayerViewController.swift │ ├── LegacyExampleViewController.swift │ ├── PluginViewController.swift │ └── en.lproj/ │ └── Main.strings ├── Makefile ├── Mintfile ├── Package.md ├── Package.swift ├── PackageModules.dot ├── Podfile ├── README.md ├── README.zh-cn.md ├── Sources/ │ ├── Animator/ │ │ ├── HeroAnimatorViewContext.swift │ │ ├── HeroCoreAnimationViewContext.swift │ │ ├── HeroDefaultAnimator.swift │ │ └── HeroViewPropertyViewContext.swift │ ├── Debug Plugin/ │ │ ├── HeroDebugPlugin.swift │ │ └── HeroDebugView.swift │ ├── Extensions/ │ │ ├── Array+HeroModifier.swift │ │ ├── CALayer+Hero.swift │ │ ├── CAMediaTimingFunction+Hero.swift │ │ ├── CG+Hero.swift │ │ ├── DispatchQueue+Hero.swift │ │ ├── Locale+Hero.swift │ │ ├── UIColor+HexString.swift │ │ ├── UIKit+Hero.swift │ │ ├── UIView+Hero.swift │ │ └── UIViewController+Hero.swift │ ├── Hero.h │ ├── HeroCompatible.swift │ ├── HeroContext.swift │ ├── HeroModifier+Advanced.swift │ ├── HeroModifier+HeroStringConvertible.swift │ ├── HeroModifier.swift │ ├── HeroPlugin.swift │ ├── HeroTargetState.swift │ ├── HeroTypes.swift │ ├── HeroViewControllerDelegate.swift │ ├── Info.plist │ ├── Parser/ │ │ ├── HeroStringConvertible.swift │ │ ├── Lexer.swift │ │ ├── Nodes.swift │ │ ├── Parser.swift │ │ └── Regex.swift │ ├── Preprocessors/ │ │ ├── BasePreprocessor.swift │ │ ├── CascadePreprocessor.swift │ │ ├── ConditionalPreprocessor.swift │ │ ├── DefaultAnimationPreprocessor.swift │ │ ├── IgnoreSubviewModifiersPreprocessor.swift │ │ ├── MatchPreprocessor.swift │ │ └── SourcePreprocessor.swift │ ├── SwiftSupport.swift │ └── Transition/ │ ├── HeroProgressRunner.swift │ ├── HeroTransition+Animate.swift │ ├── HeroTransition+Complete.swift │ ├── HeroTransition+CustomTransition.swift │ ├── HeroTransition+Interactive.swift │ ├── HeroTransition+Start.swift │ ├── HeroTransition+UINavigationControllerDelegate.swift │ ├── HeroTransition+UITabBarControllerDelegate.swift │ ├── HeroTransition+UIViewControllerTransitioningDelegate.swift │ ├── HeroTransition.swift │ └── HeroTransitionState.swift ├── Tests/ │ ├── HeroTests.swift │ └── Info.plist ├── TvOSExamples/ │ ├── AppDelegate.swift │ ├── Base.lproj/ │ │ └── Main.storyboard │ ├── Basic.storyboard │ ├── ImageGallery.storyboard │ ├── ImageViewer.storyboard │ ├── Info.plist │ └── TVImageGalleryViewController.swift ├── book.json └── docs/ ├── Classes/ │ ├── BinaryOpNode.html │ ├── CallNode.html │ ├── ExprNode.html │ ├── FunctionNode.html │ ├── Hero.html │ ├── HeroContext.html │ ├── HeroDebugPlugin.html │ ├── HeroExtension.html │ ├── HeroModifier.html │ ├── HeroPlugin.html │ ├── HeroTransition.html │ ├── Lexer.html │ ├── NumberNode.html │ ├── Parser.html │ ├── PrototypeNode.html │ └── VariableNode.html ├── Classes.html ├── Enums/ │ ├── CascadeDirection.html │ ├── HeroCoordinateSpace.html │ ├── HeroDefaultAnimationType/ │ │ ├── Direction.html │ │ └── Strategy.html │ ├── HeroDefaultAnimationType.html │ ├── HeroSnapshotType.html │ ├── HeroTransitionState.html │ ├── HeroViewOrderingStrategy.html │ ├── ParseError.html │ └── Token.html ├── Enums.html ├── Extensions/ │ ├── CAMediaTimingFunction.html │ ├── CATransform3D.html │ ├── HeroDebugView.html │ ├── String.html │ ├── UINavigationController.html │ ├── UITabBarController.html │ ├── UIView.html │ └── UIViewController.html ├── Extensions.html ├── Functions.html ├── Protocols/ │ ├── HeroAnimator.html │ ├── HeroCompatible.html │ ├── HeroCustomSnapshotView.html │ ├── HeroPreprocessor.html │ ├── HeroProgressUpdateObserver.html │ ├── HeroStringConvertible.html │ ├── HeroTransitionDelegate.html │ └── HeroViewControllerDelegate.html ├── Protocols.html ├── Structs/ │ ├── HeroConditionalContext.html │ └── HeroTargetState.html ├── Structs.html ├── css/ │ ├── highlight.css │ └── jazzy.css ├── docsets/ │ ├── Hero.docset/ │ │ └── Contents/ │ │ ├── Info.plist │ │ └── Resources/ │ │ ├── Documents/ │ │ │ ├── Classes/ │ │ │ │ ├── BinaryOpNode.html │ │ │ │ ├── CallNode.html │ │ │ │ ├── ExprNode.html │ │ │ │ ├── FunctionNode.html │ │ │ │ ├── Hero.html │ │ │ │ ├── HeroContext.html │ │ │ │ ├── HeroDebugPlugin.html │ │ │ │ ├── HeroExtension.html │ │ │ │ ├── HeroModifier.html │ │ │ │ ├── HeroPlugin.html │ │ │ │ ├── HeroTransition.html │ │ │ │ ├── Lexer.html │ │ │ │ ├── NumberNode.html │ │ │ │ ├── Parser.html │ │ │ │ ├── PrototypeNode.html │ │ │ │ └── VariableNode.html │ │ │ ├── Classes.html │ │ │ ├── Enums/ │ │ │ │ ├── CascadeDirection.html │ │ │ │ ├── HeroCoordinateSpace.html │ │ │ │ ├── HeroDefaultAnimationType/ │ │ │ │ │ ├── Direction.html │ │ │ │ │ └── Strategy.html │ │ │ │ ├── HeroDefaultAnimationType.html │ │ │ │ ├── HeroSnapshotType.html │ │ │ │ ├── HeroTransitionState.html │ │ │ │ ├── HeroViewOrderingStrategy.html │ │ │ │ ├── ParseError.html │ │ │ │ └── Token.html │ │ │ ├── Enums.html │ │ │ ├── Extensions/ │ │ │ │ ├── CAMediaTimingFunction.html │ │ │ │ ├── CATransform3D.html │ │ │ │ ├── HeroDebugView.html │ │ │ │ ├── String.html │ │ │ │ ├── UINavigationController.html │ │ │ │ ├── UITabBarController.html │ │ │ │ ├── UIView.html │ │ │ │ └── UIViewController.html │ │ │ ├── Extensions.html │ │ │ ├── Functions.html │ │ │ ├── Protocols/ │ │ │ │ ├── HeroAnimator.html │ │ │ │ ├── HeroCompatible.html │ │ │ │ ├── HeroCustomSnapshotView.html │ │ │ │ ├── HeroPreprocessor.html │ │ │ │ ├── HeroProgressUpdateObserver.html │ │ │ │ ├── HeroStringConvertible.html │ │ │ │ ├── HeroTransitionDelegate.html │ │ │ │ └── HeroViewControllerDelegate.html │ │ │ ├── Protocols.html │ │ │ ├── Structs/ │ │ │ │ ├── HeroConditionalContext.html │ │ │ │ └── HeroTargetState.html │ │ │ ├── Structs.html │ │ │ ├── css/ │ │ │ │ ├── highlight.css │ │ │ │ └── jazzy.css │ │ │ ├── index.html │ │ │ ├── js/ │ │ │ │ ├── jazzy.js │ │ │ │ ├── jazzy.search.js │ │ │ │ └── typeahead.jquery.js │ │ │ └── search.json │ │ └── docSet.dsidx │ └── Hero.tgz ├── index.html ├── js/ │ ├── jazzy.js │ ├── jazzy.search.js │ └── typeahead.jquery.js ├── search.json └── undocumented.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codecov.yml ================================================ # https://docs.codecov.io/docs/codecov-yaml codecov: require_ci_to_pass: yes coverage: precision: 2 round: down range: "70...100" ignore: - docs - Examples - LegacyExamples - Resources - TvOSExamples status: patch: default: if_no_uploads: error changes: true project: default: target: auto if_no_uploads: error comment: false ================================================ FILE: .editorconfig ================================================ # http://editorconfig.org root = true [*] indent_style = space charset = utf-8 indent_size = 4 end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true [*.{md,markdown}] trim_trailing_whitespace = false [*.{c,h,m,mm}] indent_size = 2 [*.js] indent_size = 2 [*.{swift}] indent_size = 4 [Makefile] trim_trailing_whitespace = true indent_style = tab indent_size = 8 [*.{yaml|yml}] indent_size = 2 ================================================ FILE: .github/CODEOWNERS ================================================ # CODEOWNERS # Lines starting with '#' are comments. # Each line is a file pattern followed by one or more owners. # https://help.github.com/en/articles/about-code-owners # These owners will be the default owners for everything in the repo. * @JoeMatt @lkzhao @SD10 @kuyazee ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [JoeMatt, lkzhao, SD10, kuyazee] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: herotransitions # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] ================================================ FILE: .github/auto_assign.yml ================================================ # Set to true to add reviewers to pull requests addReviewers: true # Set to true to add assignees to pull requests addAssignees: false # A list of reviewers to be added to pull requests (GitHub user name) reviewers: - JoeMatt - lkzhao - SD10 - kuyazee # A number of reviewers added to the pull request # Set 0 to add all the reviewers (default: 0) numberOfReviewers: 0 # A list of assignees, overrides reviewers if set # assignees: # A number of assignees to add to the pull request # Set to 0 to add all of the assignees. # Uses numberOfReviewers if unset. numberOfAssignees: 1 # A list of keywords to be skipped the process that add reviewers if pull requests include it skipKeywords: - wip - WIP ================================================ FILE: .github/issue_template.md ================================================ ## What did you do? ## What did you expect to happen? ## What happened instead? ## General Information * Hero Version: * iOS Version(s): * Swift Version: * Devices/Simulators: * Reproducible in Examples? (Yes/No): ## Demo Project ================================================ FILE: .github/main.workflow ================================================ action "Danger" { uses = "danger/danger" # secrets = ["GITHUB_TOKEN"] } ================================================ FILE: .github/stale.yml ================================================ # Number of days of inactivity before an issue becomes stale daysUntilStale: 180 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Issues with these labels will never be considered stale exemptLabels: - pinned - security - confirmed bug - investigating - bug? - WIP # Label to use when marking an issue as stale staleLabel: stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. # Comment to post when closing a stale issue. Set to `false` to disable closeComment: true ================================================ FILE: .github/workflows/build.yml ================================================ on: push: branches: - master name: Build jobs: test: name: Build runs-on: macOS-latest strategy: matrix: destination: [ 'platform=Any iOS Simulator', 'platform=Any tvOS Simulator', 'platform=macOS,arch=x86_64', 'platform=macOS,arch=arm64', 'platform=macCatalyst,arch=x86_64', 'platform=macCatalyst,arch=arm64', ] steps: - name: Checkout uses: actions/checkout@master - name: Build run: | pod install set -o pipefail && \ xcodebuild clean build \ -workspace Hero.xcworkspace \ -scheme Hero \ -destination "${destination}" \ -parallelizeTargets -showBuildTimingSummary \ -enableCodeCoverage YES \ CODE_SIGN_IDENTITY="" \ CODE_SIGNING_REQUIRED=NO \ | xcpretty env: destination: ${{ matrix.destination }} ================================================ FILE: .github/workflows/rebase.yml ================================================ # Rebase PR branch when someone comments /rebase on: issue_comment: types: [created] name: Automatic Rebase jobs: rebase: name: Rebase if: contains(github.event.comment.body, '/rebase') runs-on: ubuntu-latest steps: - uses: actions/checkout@master - name: Automatic Rebase uses: cirrus-actions/rebase@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/swiftlint.yml ================================================ name: Swift Lint on: pull_request: paths: - '.github/workflows/swiftlint.yml' - '.swiftlint.yml' - '**/*.swift' jobs: swift-lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: GitHub Action for SwiftLint uses: norio-nomura/action-swiftlint@3.2.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DIFF_BASE: ${{ github.base_ref }} ================================================ FILE: .github/workflows/test.yml ================================================ # test.yml # Unit Test name: Unit Test 'on': pull_request: paths: - '**.swift' - '**.xcodeproj' - '**.m' - '**.h' - '**.podspec' - Podfile - Podfile.lock - '**/test.yml' jobs: swiftpm: name: Test iOS (swiftpm) runs-on: macOS-latest env: DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master - name: iOS - Swift PM run: | pod install set -o pipefail && swift test --parallel XCode: name: Test iOS runs-on: macOS-latest env: DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer strategy: matrix: run-config: - scheme: Hero platform: iOS action: test code-coverage: true - scheme: Hero (tvOS) platform: tvOS action: build code-coverage: false steps: - name: Checkout uses: actions/checkout@master - name: CocoaPods - ${{ matrix.run-config.destination }} run: | pod install - name: Test - ${{ matrix.run-config.platform }} uses: mxcl/xcodebuild@v2.0 with: platform: ${{ matrix.run-config.platform }} action: ${{ matrix.run-config.action }} code-coverage: ${{ matrix.run-config.code-coverage }} configuration: Debug scheme: ${{ matrix.run-config.scheme }} workspace: Hero.xcworkspace - name: Upload Code Coverage uses: codecov/codecov-action@v3 if: ${{ matrix.run-config.code-coverage }} with: token: ${{ secrets.CODECOV_TOKEN }} ================================================ FILE: .gitignore ================================================ .DS_Store # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore ## Build generated build/ DerivedData/ ## Various settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata/ ## Other *.moved-aside *.xcuserstate ## Obj-C/Swift specific *.hmap *.ipa *.dSYM.zip *.dSYM ## Playgrounds timeline.xctimeline playground.xcworkspace # Swift Package Manager # # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. # Packages/ .build/ # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # Pods/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # screenshots whenever they are needed. # For more information about the recommended setup visit: # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md fastlane/report.xml fastlane/Preview.html fastlane/screenshots fastlane/test_output # Gitbook node_modules _book xcodebuild.log .swiftpm /.bundle *.zip ================================================ FILE: .jazzy.yaml ================================================ # ---- About ---- module: Hero module_version: 1.6.4 author: HeroTransitions readme: README.md copyright: 'See [license](https://github.com/HeroTransitions/Hero/blob/develop/LICENSE) for more details.' # ---- URLs ---- author_url: https://herotransitions.github.io/Hero/ dash_url: https://herotransitions.github.io/Hero/docsets/Hero.xml github_url: https://github.com/HeroTransitions/Hero/ github_file_prefix: https://github.com/HeroTransitions/Hero/tree/1.6.2/ # ---- Sources ---- podspec: Hero.podspec # ---- Generation ---- clean: true output: docs min_acl: public hide_documentation_coverage: false skip_undocumented: false objc: false # swift_version: 5.1.0 # ---- Formatting ---- theme: fullwidth ================================================ FILE: .makefiles/bundler.mk ================================================ # Provides a dependecy, `bundle`, which runs bundle install when necessary. # Override bundle install options by setting BUNDLE_INSTALL_OPTS. BE := bundle exec BUNDLE_INSTALL_OPTS ?= Gemfile.lock: Gemfile FORCE | _program_bundle @bundle check > /dev/null 2>&1 && \ ( $(call _log,rubygems up-to-date) ) || \ ( $(call _log,installing rubygems); \ bundle install $(BUNDLE_INSTALL_OPTS) ) #> installs rubygems bundle:: Gemfile.lock .PHONY: bundle ================================================ FILE: .makefiles/docker-compose.mk ================================================ DOCKER_COMPOSE_PULL ?= yes DOCKER_COMPOSE_DAEMON ?= yes DOCKER_COMPOSE_FILE ?= docker-compose.yml DOCKER_COMPOSE_UP_FLAGS += $(if $(filter yes,$(DOCKER_COMPOSE_DAEMON)),-d) DOCKER_COMPOSE_BUILD_FLAGS += $(if $(filter yes,$(DOCKER_COMPOSE_PULL)),--pull) DOCKER_COMPOSE_CLEAN_FLAGS ?= --rmi all --volumes --remove-orphans .docker-compose-build-complete: @[ -f .gitignore -a -z "$$(grep '$@' .gitignore 2> /dev/null)" ] && \ ( $(call _warn,WARNING: $@ not found in .gitignore) ) || true $(call log,building from $(DOCKER_COMPOSE_FILE)) docker-compose -f $(DOCKER_COMPOSE_FILE) build $(DOCKER_COMPOSE_BUILD_FLAGS) @touch $@ #> build docker images (force rebuild with -B) build:: .docker-compose-build-complete | _program_docker-compose .PHONY: build #> run docker-compose up up:: build | _program_docker-compose $(call log,starting docker services in $(DOCKER_COMPOSE_FILE)) docker-compose -f $(DOCKER_COMPOSE_FILE) up $(DOCKER_COMPOSE_UP_FLAGS) .PHONY: up #> run docker-compose down down:: | _program_docker-compose $(call log,stopping docker services in $(DOCKER_COMPOSE_FILE)) docker-compose -f $(DOCKER_COMPOSE_FILE) down .PHONY: down #> remove docker-compose artifacts clean:: | _program_docker-compose $(call log,cleaning up docker artifacts) docker-compose -f $(DOCKER_COMPOSE_FILE) down $(DOCKER_COMPOSE_CLEAN_FLAGS) rm -f .docker-compose-build-complete .PHONY: clean ================================================ FILE: .makefiles/help.awk ================================================ # Awk program for automatically generating help text from those ludicrous makefiles. # See help.mk for details. function len(a, i, k) { for (i in a) k++ return k } function join(a, sep) { result = "" if (sep == "") sep = SUBSEP for (item in a) result = result sep a[item] return result } function unjoin(a, text, sep) { if (sep == "") sep = SUBSEP split(substr(text, 2), a, sep) } function append(a, item) { a[len(a) + 1] = item } function extend(a, b) { for (item in b) append(a, b[item]) } /^#> / { comments[++comments_counter] = substr($0, 4) } /^[^: \t]*:[^;]*;?/ { split($0, recipe_firstline, ":") target = recipe_firstline[1] width = length(target) max_width = (max_width > width) ? max_width : width if ( substr(lastline, 1, 2) == "#>" ) { target_docs[target] = join(comments, "#") delete comments } } !/^#>/ { if (len(comments) > 0) { extend(global_docs, comments) append(global_docs, "") delete comments } } { lastline = $0 } END { for (doc in global_docs) print global_docs[doc] printf "Targets:\n" for (target in target_docs) { unjoin(help, target_docs[target], "#") printf " %-" max_width "s %s\n", target, help[1] for (i = 2; i <= len(help); i++) printf " %-" max_width "s %s\n", "", help[i] } } ================================================ FILE: .makefiles/ios.mk ================================================ SHELL := /bin/bash .PHONY: help update pull bootstrap RUBY := $(shell command -v ruby 2>/dev/null) CARTHAGE := $(shell command -v carthage 2>/dev/null) PODS := $(shell command -v pod 2>/dev/null) HOMEBREW := $(shell command -v brew 2>/dev/null) ROME := $(shell command -v rome 2>/dev/null) BUNDLER := $(shell command -v bundle 2>/dev/null) CARTING := $(shell command -v carting 2>/dev/null) SWIFTGEN := $(shell command -v swiftgen 2>/dev/null) SWIFTLINT := $(shell command -v swiftlint 2>/dev/null) PLATFORM := 'iOS,tvOS,macOS,watchOS' WORKSPACE := '$(shell ls -d *.xc* | head -1)' default: help # Add the following 'help' target to your Makefile # And add help text after each target name starting with '\#\#' # A category can be added with @category # COLORS GREEN := $(shell tput -Txterm setaf 2) YELLOW := $(shell tput -Txterm setaf 3) WHITE := $(shell tput -Txterm setaf 7) RESET := $(shell tput -Txterm sgr0) #>----- Helper functions ------ # Helper target for declaring an external executable as a recipe dependency. # For example, # `my_target: | _program_awk` # will fail before running the target named `my_target` if the command `awk` is # not found on the system path. _program_%: FORCE @_=$(or $(shell which $* 2> /dev/null),$(error `$*` command not found. Please install `$*` and try again)) # Helper target for declaring required environment variables. # # For example, # `my_target`: | _var_PARAMETER` # # will fail before running `my_target` if the variable `PARAMETER` is not declared. _var_%: FORCE @_=$(or $($*),$(error `$*` is a required parameter)) _tag: | _var_VERSION make --no-print-directory -B README.md git commit -am "Tagging release $(VERSION)" git tag -a $(VERSION) $(if $(NOTES),-m '$(NOTES)',-m $(VERSION)) .PHONY: _tag _push: | _var_VERSION git push origin $(VERSION) git push origin master .PHONY: _push #> Install dependencies. setup: \ pre_setup \ check_for_ruby \ check_for_homebrew \ update_homebrew \ install_carthage \ install_bundler_gem \ install_ruby_gems \ install_carthage_dependencies #> Install extra tools (carting, swiftlint, swift-gen...) install_extras: pre_setup \ check_for_ruby \ check_for_homebrew \ update_homebrew \ install_carthage \ install_swift_lint \ install_carting \ install_rome \ install_swiftgen pull_request: \ test \ codecov_upload \ danger pre_setup: $(info iOS project setup ...) check_for_ruby: $(info Checking for Ruby ...) ifeq ($(RUBY),) $(error Ruby is not installed) endif check_for_homebrew: $(info Checking for Homebrew ...) ifeq ($(HOMEBREW),) $(error Homebrew is not installed) endif update_homebrew: $(info Update Homebrew ...) brew update install_swift_lint: $(info Install swiftlint ...) ifneq ($(SWIFTLINT),) brew install swiftlint else $(info Already have, skipping.) endif install_bundler_gem: $(info Checking and install bundler ...) ifeq ($(BUNDLER),) gem install bundler -v '~> 1.17' else gem update bundler '~> 1.17' endif install_ruby_gems: $(info Install Ruby Gems ...) bundle check || bundle install install_carthage: $(info Install Carthage ...) ifneq ($(CARTHAGE),) brew install carthage else $(info Already have, skipping.) endif install_carting: $(info Install Carting ...) ifneq ($(CARTING),) brew install artemnovichkov/projects/carting else $(info Already have, skipping.) endif install_swiftgen: $(info Install Swift-Gen (https://github.com/SwiftGen/SwiftGen) ...) ifneq ($(SWIFTGEN),) brew install swiftgen else $(info Already have, skipping.) endif gitpull: $(info Pulling new commits ...) git pull #> -- QA Task Runners -- codecov_upload: curl -s https://codecov.io/bash | bash #> Danger a GitHub PR Locally. Useage `make danger_pr PR={PR#} autocorrect danger_pr: bundle exec danger pr "$(GITHUB_URL:/=)/pull/$(PULL)" danger: bundle exec danger #> SwiftLint autocorrect autocorrect: bundle exec swiftlint autocorrect --config .swiftlint.yml ## -- Testing -- #> Run test on all targets test: xcodebuild test -scheme $(TEST_SCHEME) -workspace $(WORKSPACE) -destination 'platform=iOS Simulator,OS=14.4,name=iPhone 12' -parallelizeTargets -showBuildTimingSummary -enableThreadSanitizer YES CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | tee xcodebuild.log | xcpretty #> -- Building -- #> Make a .zip package of frameworks package: carthage build --no-skip-current --platform $(PLATFORM) --use-xcframeworks --cache-builds carthage archive $(MODULE_NAME) #> tag and release to github release: | _var_VERSION @if ! git diff --quiet HEAD; then \ ( $(call _error,refusing to release with uncommitted changes) ; exit 1 ); \ fi test package make --no-print-directory _tag VERSION=$(VERSION) make --no-print-directory _push VERSION=$(VERSION) #> Open the workspace open: open $(WORKSPACE) #> Setup the project, git-hooks etc init: git config core.hooksPath .githooks ================================================ FILE: .makefiles/ludicrous.mk ================================================ # The "main" utility functions and helpers useful for the common case. Most # ludicrous makefiles require this file, so it's sensible to `include` it first. INCLUDES_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) LUDICROUS_BRANCH := master LUDICROUS_DOWNLOAD_URL := https://raw.githubusercontent.com/martinwalsh/ludicrous-makefiles/$(LUDICROUS_BRANCH)/includes # Generates help text from specialized comments (lines prefixed with a `#>`). # Free-standing comments are included in the prologue of the help text, while # those immediately preceding a recipe will be displayed along with their # respective target names # # Targets: help # Requires: awk # Side effects: # * .DEFAULT_GOAL is set to to the `help` target from this file # HELP_PROGRAM := $(INCLUDES_DIR)/help.awk # COLORS GREEN := $(shell tput -Txterm setaf 2) YELLOW := $(shell tput -Txterm setaf 3) WHITE := $(shell tput -Txterm setaf 7) RESET := $(shell tput -Txterm sgr0) #> displays this message # help: _HELP_F := $(firstword $(MAKEFILE_LIST)) # help: | _program_awk # @awk -f $(HELP_PROGRAM) $(wordlist 2,$(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) $(_HELP_F) # always prefer help from the top-level makefile TARGET_MAX_CHAR_NUM=20 #> Show help help: @echo '' @echo 'Usage:' @echo ' ${YELLOW}make${RESET} ${GREEN}${RESET}' @echo '' @echo 'Targets:' @awk '/^[a-zA-Z\-\0-9]+:/ { \ helpMessage = match(lastLine, /^#> (.*)/); \ if (helpMessage) { \ helpCommand = substr($$1, 0, index($$1, ":")-1); \ helpMessage = substr(lastLine, RSTART + 3, RLENGTH); \ printf " ${YELLOW}%-$(TARGET_MAX_CHAR_NUM)s${RESET} ${GREEN}%s${RESET}\n", helpCommand, helpMessage; \ } \ } \ { lastLine = $$0 }' \ $(MAKEFILE_LIST) .PHONY: help .DEFAULT_GOAL := help # Helper target for declaring an external executable as a recipe dependency. # For example, # `my_target: | _program_awk` # will fail before running the target named `my_target` if the command `awk` is # not found on the system path. _program_%: FORCE @_=$(or $(shell which $* 2> /dev/null),$(error `$*` command not found. Please install `$*` and try again)) # Helper target for declaring required environment variables. # # For example, # `my_target`: | _var_PARAMETER` # # will fail before running `my_target` if the variable `PARAMETER` is not declared. _var_%: FORCE @_=$(or $($*),$(error `$*` is a required parameter)) # The defult build dir, if we have only one it'll be easier to cleanup BUILD_DIR =: build $(BUILD_DIR): mkdir -p $@ # text manipulation helpers _awk_case = $(shell echo | awk '{ print $(1)("$(2)") }') lc = $(call _awk_case,tolower,$(1)) uc = $(call _awk_case,toupper,$(1)) # Useful for forcing targets to build when .PHONY doesn't help FORCE: .PHONY: FORCE # Provides two callables, `log` and `_log`, to facilitate consistent # user-defined output, formatted using tput when available. # # Override TPUT_PREFIX to alter the formatting. TPUT := $(shell which tput 2> /dev/null) TPUT_PREFIX := $(TPUT) bold TPUT_SUFFIX := $(TPUT) sgr0 TPUT_RED := $(TPUT) setaf 1 TPUT_GREEN := $(TPUT) setaf 2 TPUT_YELLOW := $(TPUT) setaf 3 LOG_PREFIX ?= ===> ifeq (,$(and $(TPUT),$(TERM))) define _log echo "$(if $(LOG_PREFIX),$(LOG_PREFIX) )$(1)" endef define _warn echo "$(if $(LOG_PREFIX),$(LOG_PREFIX) )$(1)" endef define _error echo "$(if $(LOG_PREFIX),$(LOG_PREFIX) )$(1)" endef else define _log $(TPUT_PREFIX); echo "$(if $(LOG_PREFIX),$(LOG_PREFIX) )$(1)"; $(TPUT_SUFFIX) endef define _warn $(TPUT_PREFIX); $(TPUT_YELLOW); echo "$(if $(LOG_PREFIX),$(LOG_PREFIX) )$(1)"; $(TPUT_SUFFIX) endef define _error $(TPUT_PREFIX); $(TPUT_RED); echo "$(if $(LOG_PREFIX),$(LOG_PREFIX) )$(1)"; $(TPUT_SUFFIX) endef endif define log @$(_log) endef # Removes build artifacts, implement with your own `clean::` target to remove additional artifacts. # See https://www.gnu.org/software/make/manual/make.html#Double_002dColon for more information. #> removes build artifacts clean:: @: .PHONY: clean # Provides callables `download` and `download_to`. # * `download`: fetches a url `$(1)` piping it to a command specified in `$(2)`. # Usage: `$(call download,$(URL),tar -xf - -C /tmp/dest)` # # * `download_to`: fetches a url `$(1)` and writes it to a local path specified in `$(2)`. # Usage: `$(call download_to,$(URL),/tmp/dest)` # # Requires: curl # # Additional command line parameters may be passed to curl via CURL_OPTS. # For example, `CURL_OPTS += -s`. # CURL_OPTS ?= --location --silent ifneq ($(shell which curl 2> /dev/null),) DOWNLOADER = curl $(CURL_OPTS) DOWNLOAD_FLAGS := DOWNLOAD_TO_FLAGS := --write-out "%{http_code}" -o else NO_DOWNLOADER_FOUND := Unable to locate a suitable download utility (curl) endif define download $(if $(NO_DOWNLOADER_FOUND),$(error $(NO_DOWNLOADER_FOUND)),$(DOWNLOADER) $(DOWNLOAD_FLAGS) "$(1)" | $(2)) endef define download_to $(if $(NO_DOWNLOADER_FOUND),$(error $(NO_DOWNLOADER_FOUND)),$(DOWNLOADER) $(DOWNLOAD_TO_FLAGS) $(2) "$(1)") endef # Provides variables useful for determining the operating system we're running # on. # # OS_NAME will reflect the name of the operating system: Darwin, Linux or Windows # OS_CPU will be either x86 (32bit) or amd64 (64bit) # OS_ARCH will be either i686 (32bit) or x86_64 (64bit) # ifeq (Windows_NT,$(OS)) OS_NAME := Windows OS_CPU := $(call _lower,$(PROCESSOR_ARCHITECTURE)) OS_ARCH := $(if $(findstring amd64,$(OS_CPU)),x86_64,i686) else OS_NAME := $(shell uname -s) OS_ARCH := $(shell uname -m) OS_CPU := $(if $(findstring 64,$(OS_ARCH)),amd64,x86) endif # Install ludicrous plugins by include directive PLUGIN_TARGETS := $(abspath $(INCLUDES_DIR)/%.mk) $(subst $(CURDIR)/,,$(abspath $(INCLUDES_DIR)/%.mk)) ifneq (B,$(findstring B,$(MAKEFLAGS))) $(PLUGIN_TARGETS): @[ ! -f $@ ] && \ ( \ $(call _log,downloading ludicrous plugin to $@); \ STATUS="$$($(call download_to,$(LUDICROUS_DOWNLOAD_URL)/$(notdir $@),$@))"; \ if [ $$STATUS -ne 200 ]; then $(call _error,ludicrous plugin $(notdir $@) not found.); exit 1; fi \ ) else $(PLUGIN_TARGETS): @: endif ================================================ FILE: .makefiles/virtualenv.mk ================================================ # Provides a dependecy, `virtualenv`, which creates a local virtualenv for use # during development of a python project. PYTHON_VERSION ?= VIRTUALENV_DIR ?= .env PIP_INDEX_URL ?= PIP_REQUIREMENTS ?= requirements.txt PYTHON := python$(PYTHON_VERSION) PIP := $(VIRTUALENV_DIR)/bin/pip PIP_INDEX_FLAG := $(if $(PIP_INDEX_URL),--index-url $(PIP_INDEX_URL)) $(VIRTUALENV_DIR): | _program_$(PYTHON) _program_virtualenv ${call log,creating virtualenv at $(VIRTUALENV_DIR)} virtualenv --python=$(PYTHON) $(VIRTUALENV_DIR) $(PIP): $(PIP_REQUIREMENTS) | $(VIRTUALENV_DIR) ${call log,install python dependencies from $(PIP_REQUIREMENTS)} $(PIP) install $(PIP_INDEX_FLAG) --upgrade pip setuptools $(PIP) install $(PIP_INDEX_FLAG) --upgrade -r $(PIP_REQUIREMENTS) @touch $(PIP) #> installs python dependencies virtualenv:: $(PIP) .PHONY: virtualenv clean:: rm -rf $(VIRTUALENV_DIR) .PHONY: clean ================================================ FILE: .swiftlint.yml ================================================ disabled_rules: # rule identifiers to exclude from running - missing_docs - unused_closure_parameter - identifier_name - weak_delegate - cyclomatic_complexity - function_body_length - todo - large_tuple opt_in_rules: # some rules are only opt-in - empty_count # Find all the available rules by running: # swiftlint rules included: # paths to include during linting. `--path` is ignored if present. - Sources excluded: # paths to ignore during linting. Takes precedence over `included`. - Carthage - Pods # configurable rules can be customized from this configuration file # binary rules can set their severity level force_cast: warning # implicitly force_try: severity: warning # explicitly # rules that have both warning and error levels, can set just the warning level # implicitly line_length: 500 # they can set both implicitly with an array type_body_length: - 300 # warning - 400 # error # or they can set both explicitly file_length: warning: 600 error: 1200 # naming rules can set warnings/errors for min_length and max_length # additionally they can set excluded names type_name: min_length: 3 # only warning max_length: # warning and error warning: 40 error: 50 excluded: # excluded via string - T - t identifier_name: min_length: # only min_length error: 3 # only error excluded: # excluded via string array - id - vc - to - a - b - t - x - y - z - p - xy - dx - dy - gr ================================================ FILE: .travis.yml ================================================ language: - swift osx_image: xcode11.0 script: - xcodebuild -scheme HeroExamples -workspace Hero.xcworkspace -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone X,OS=13.0' build test after_success: - bash <(curl -s https://codecov.io/bash) ================================================ FILE: CHANGELOG.md ================================================ # CHANGELOG The changelog for `Hero`. Also see the [releases](https://github.com/HeroTransitions/Hero/releases) on GitHub. -------------------------------------- ## [1.6.4](https://github.com/HeroTransitions/Hero/releases/tag/1.6.4) - Fix XCode 16 ## [1.6.3](https://github.com/HeroTransitions/Hero/releases/tag/1.6.3) - 1ac98e7 Adaption for visionOS. - 5e05761 Merge pull request #771 from HeroTransitions/feature/CICDFix - c9a98cf CI/CI build and test, matrix platforms fix? - 2f8096d build.yml test.yml update github runner env - 45aed92 Readme add api docs link - a7d2682 README.md update ios/xcode version badges - 211df4b README.md Add unit test and swift pm action badges - bff4221 swiftlint fix - a47dce4 Merge pull request #749 from tadija/feature/xcode14-warnings - fd2ba86 Fix lint warnings - 5c053a6 Fix build warnings with Xcode 14.0 ## [1.6.2](https://github.com/HeroTransitions/Hero/releases/tag/1.6.2) ### Fixed - [#717](https://github.com/HeroTransitions/Hero/issues/717) - [#734](https://github.com/HeroTransitions/Hero/issues/734) - [#735](https://github.com/HeroTransitions/Hero/issues/735) - [#736](https://github.com/HeroTransitions/Hero/issues/736) - [#739](https://github.com/HeroTransitions/Hero/issues/739) - [#740](https://github.com/HeroTransitions/Hero/issues/740) Fix build warings in XCode 13.4.1 c30a7a867d3bc420e90ad276d9bf12287628ce87 - [#742](https://github.com/HeroTransitions/Hero/issues/742) Add `anchorPoint` support for transitioning a76e9f6dbeefb530743994634d37235e59401911 ## [1.6.1](https://github.com/HeroTransitions/Hero/releases/tag/1.6.1) ### Added - git ignore .zip files ### Changed - closes #703 Move CI depends to Mint ### Fixed - Update README.md remove dead link closes #708 - Update the link to material design's motion duration easing links. - fixes #704 SPM missing imports ## [1.6.0](https://github.com/HeroTransitions/Hero/releases/tag/1.6.0) ### Added - #695 - Swift 5 support - #628 - Swift Package Manager Support - #623 - Swift UI support and example - #681 - Application extension target support - #595 - Add Accio supported badge - #619 - XCode 11/12 support in example - CI/CD improvements ### Changed - #648 - Updated iOS version support - #576 - Usage guide updates ### Fixed - #698 - Warnings fix - #585 - replaceViewControllers now calls the completion - #559 - Resuming property animator from current fraction - #465 - fix keyboard transition ## [1.5.0](https://github.com/HeroTransitions/Hero/releases/tag/1.5.0) ### Added - Use custom snapshot for views that implement `HeroCustomSnapshotView`. [#541](https://github.com/HeroTransitions/Hero/pull/541) by [@ManueGE](https://github.com/ManueGE) ### Changed - Added support for right to left languages. [#520](https://github.com/HeroTransitions/Hero/pull/520) by [@ManueGE](https://github.com/ManueGE) - The hidden state of subviews are now taken into account in optimized snapshot type for `UIImageView`. [#521](https://github.com/HeroTransitions/Hero/pull/521) by [@ManueGE](https://github.com/ManueGE) ## [1.4.0](https://github.com/HeroTransitions/Hero/releases/tag/1.4.0) ### Added - Added support for Swift 4.2. [#534](https://github.com/HeroTransitions/Hero/pull/534) by [@rennarda](https://github.com/rennarda) ## [1.3.1](https://github.com/HeroTransitions/Hero/releases/tag/1.3.1) ### Fixed - Fixed the retain cycle caused by strong references to `previousNavigationDelegate` and `previousTabBarDelegate`. [#516](https://github.com/HeroTransitions/Hero/pull/516) by [@mkieselmann](https://github.com/mkieselmann) ## [1.3.0](https://github.com/HeroTransitions/Hero/releases/tag/1.3.0) ### Added - Adds an optional completion block parameter to the `dismissViewController` and `replaceViewController` methods. [#456](https://github.com/HeroTransitions/Hero/pull/456) by [@kartikthapar](https://github.com/kartikthapar) ### Changed - Allows previous `UINavigationController` delegate to handle delegate events. [#430](https://github.com/HeroTransitions/Hero/pull/430) by [@bradphilips](https://github.com/bradphilips) ### Fixed - Fixed shadows being cutoff by snapshots. [#440](https://github.com/HeroTransitions/Hero/pull/440) by [@2blane](https://github.com/2blane) - Fixed animation flickering on CALayer animation. [f4dab9](https://github.com/HeroTransitions/Hero/commit/f4dab9ed2ab88ae065605199d5aca7706b07c2ad) by [@lkzhao](https://github.com/lkzhao) ================================================ FILE: DEVELOP.md ================================================ # Develop.md ## Releases 1. Make release brach `git-flow release start x.x.x` 2. Search find/replace current version in XCode project 3. Update `CHANGELOG.md` 4. Run swift lint autocorrect `make autocorrect` 5. Change version in `jazzy.yml` 6. Run `make jazzy` 7. Commit changes. 8. Create GitHub release 9. Create CocoaPods release 1. ` pod lib lint` 10. Finish release 1. `git-flow release finish x.x.x` 2. `git push --tags` 11. Public CocoaPod release 1. `pod trunk push` ================================================ FILE: Dangerfile ================================================ # frozen_string_literal: true # Dangerfile # To test locally, use the following # `export DANGER_GITHUB_API_TOKEN=...YourToken...` # `bundle exec danger pr https://github.com/HeroTransitions/Hero/pull/1618` Or some other pull # # import remote Dangerfile; example, https://github.com/loadsmart/dangerfile/blob/master/Dangerfile # danger.import_dangerfile(github: 'loadsmart/dangerfile', :path => 'Dangerfile') require 'git_diff_parser' # ------------------------------------------------------------------------------ # Additional pull request data # ------------------------------------------------------------------------------ pr_number = github.pr_json['number'] pr_url = github.pr_json['_links']['html']['href'] # Sometimes it's a README fix, or something like that - which isn't relevant for # including in a project's CHANGELOG for example declared_trivial = github.pr_title.include? '#trivial' has_changelog_changes = git.modified_files.include?('CHANGELOG.md') has_ruby_changes = !git.modified_files.include?('Gemfile') has_podfile_changes = !git.modified_files.include?('Podfile') has_library_changes = !git.modified_files.grep(%r{Sources/*/*.swift}).empty? has_app_changes = !git.modified_files.grep(%r{Examples/*/*.swift}).empty? has_test_changes = !git.modified_files.grep(%r{Tests/*/*.swift}).empty? has_danger_changes = !git.modified_files.grep(%r{Dangerfile|script/oss-check}).empty? has_pod_lock_changes = !git.modified_files.grep(/Podfile.lock|Manifest.lock/).empty? modified_xcode_project = !git.modified_files.grep(/.*\.xcodeproj/).empty? added_swift_library_files = !git.added_files.grep(/Sources.*\.swift/).empty? deleted_swift_library_files = !git.deleted_files.grep(/Sources.*\.swift/).empty? ## Warnings # Warn when there is a big PR warn('Big PR') if git.lines_of_code > 500 # Warn when Danger changes warn('Dangerfile changes') if has_danger_changes # Warn when Ruby changes warn('Ruby Gem changes') if has_ruby_changes # Warn when Pod changes warn('Cocoapods Changes') if has_podfile_changes # Warn when Podfile changes but no lockfile warn('Podfile changes but lockfile unchanged. Did you forget to run `pod install`?') if has_podfile_changes && !has_pod_lock_changes warn 'PR is classed as Work in Progress' if github.pr_title.include? 'WIP' warn 'PR is classed as Hold' if github.pr_labels.include? 'ON HOLD' # NOTE WHEN A PR CANNOT BE MANUALLY MERGED, WHICH GOES AWAY WHEN YOU CAN can_merge = github.pr_json['mergeable'] warn('This PR cannot be merged yet.', sticky: false) unless can_merge requires_proj_update = added_swift_library_files || deleted_swift_library_files failure 'Added or removed library files require the Xcode project to be updated.' if requires_proj_update && !modified_xcode_project # ------------------------------------------------------------------------------ # Have you updated CHANGELOG.md? # ------------------------------------------------------------------------------ if !has_changelog_changes && has_library_changes markdown <<-MARKDOWN Here's an example of a CHANGELOG.md entry (place it immediately under the `* Your contribution here!` line): ```markdown * [##{pr_number}](#{pr_url}): #{github.pr_title} - [@#{github.pr_author}](https://github.com/#{github.pr_author}) ``` MARKDOWN warn('Please update CHANGELOG.md with a description of your changes. '\ 'If this PR is not a user-facing change (e.g. just refactoring), '\ 'you can disregard this.', sticky: false) end ## Messages # - > + message('Good job on cleaning the code!') if git.deletions > git.insertions ## Failures # Mainly to encourage writing up some reasoning about the PR, rather than # just leaving a title failure 'Please provide a summary in the Pull Request description' if github.pr_body.length < 5 # ONLY ACCEPT PRS TO THE DEVELOP BRANCH failure 'Please re-submit this PR to develop, we may have already fixed your issue.' if github.branch_for_base != 'develop' # Ensure a clean commits history failure 'Please rebase to get rid of the merge commits in this PR' if git.commits.any? { |c| c.message =~ /^Merge branch '#{github.branch_for_base}'/ } # Adds labels # Hold on_hold_label = 'On Hold' if github.pr_title.include? 'HOLD' auto_label.set(github.pr_json['number'], on_hold_label, 'ff8a04') else auto_label.remove(on_hold_label) end # Check if PR is mergeable merge_conflict_label = 'Merge Conflicts' if github.pr_json['mergeable'] auto_label.remove(merge_conflict_label) else auto_label.set(github.pr_json['number'], merge_conflict_label, 'e0f76f') end ### Everything here only happens if has code changes to Hero library/app code or this file. return unless has_library_changes || has_danger_changes || has_app_changes # Non-trivial amounts of app changes without tests if git.lines_of_code > 50 && has_library_changes && !has_test_changes warn 'This PR may need tests.' end if git.lines_of_code > 50 && has_library_changes && !has_app_changes warn 'This PR may need example app additions.' end # Run SwiftLint and comment on lines with violations swiftlint.config_file = '.swiftlint.yml' swiftlint.binary_path = 'Pods/SwiftLint/swiftlint' # Only lint files from this PR diff = GitDiffParser::Patches.parse(github.pr_diff) dir = "#{Dir.pwd}/" swiftlint.lint_files(inline_mode: true) do |violation| diff_filename = violation['file'].gsub(dir, '') file_patch = diff.find_patch_by_file(diff_filename) !file_patch.nil? && file_patch.changed_lines.any? { |line| line.number == violation['line'] } end # Codecov xcov.report() ================================================ FILE: Examples/AppStoreCardExample.swift ================================================ import UIKit import Hero import CollectionKit /*: # App Store Transition This is a much more advanced transition mimicking the iOS 11 App Store. It is intended to demostrate Hero's ability in creating an advance transition. It does not look 100% like the app store and the article page currently doesn't scroll. There are a few advance technique that is used in this example: 1. Interactive transition When dismissing, a pan gesture recognizer is used to adjust the progress of the transition. When user lift its finger, we determine whether or not we should cancel or finish the transition by how far the user have moved and how fast the user is moving. See `@objc func handlePan(gr: UIPanGestureRecognizer)` down below for detail. 2. The `.useNoSnapshot` modifier Whenever this modifier is used on a view, Hero won't create snapshot for that view during the transition. Instead, hero will grab the view from its superview, insert it into the transition container view, and use it directly during the transition. A few things to point out when using `.useNoSnapshot`: 1. It improves the performance a lot! since snapshot takes a long time to create. 2. It doesn't work with auto layout. This is because Hero will remove the view from its original view hierarchy. Therefore, breaking all the constraints. 3. Becareful of when to layout the cell. Do not set the `frame` of the cell when Hero is using it for transition. Otherwise it will create weird effect during the transition. If you are using `layoutSubviews` to layout a child view with `.useNoSnapshot`, first check whether or not the child view is still your child by verifying `childView.superview == self` before actually setting the frame of the child view. This way, you won't accidentally modify the child view's frame during the transition. The child view's superview will not be the original superview during a transiton, but when it finishes, Hero will insert the view back to its original view hierarchy. 3. Setting `hero.modalAnimationType` to `.none` without this, a fade animation will be applied to the destination root view. Since we use a visual effect view as our background and applied `.fade` hero modifier manually, we don't need the builtin fade animation anymore. Also when dismissing, we don't want the background view to fade in, instead, we want it to be opaque through out the transition. */ class CardView: UIView { let titleLabel = UILabel() let subtitleLabel = UILabel() let imageView = UIImageView(image: #imageLiteral(resourceName: "Unsplash6")) let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light)) required init?(coder aDecoder: NSCoder) { fatalError() } override init(frame: CGRect) { super.init(frame: frame) clipsToBounds = true titleLabel.font = UIFont.boldSystemFont(ofSize: 32) subtitleLabel.font = UIFont.systemFont(ofSize: 17) imageView.contentMode = .scaleAspectFill addSubview(imageView) addSubview(visualEffectView) addSubview(titleLabel) addSubview(subtitleLabel) } override func layoutSubviews() { super.layoutSubviews() imageView.frame = bounds visualEffectView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 90) titleLabel.frame = CGRect(x: 20, y: 20, width: bounds.width - 40, height: 30) subtitleLabel.frame = CGRect(x: 20, y: 50, width: bounds.width - 40, height: 30) } } class RoundedCardWrapperView: UIView { let cardView = CardView() var isTouched: Bool = false { didSet { var transform = CGAffineTransform.identity if isTouched { transform = transform.scaledBy(x: 0.96, y: 0.96) } UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: { self.transform = transform }, completion: nil) } } required init?(coder aDecoder: NSCoder) { fatalError() } override init(frame: CGRect) { super.init(frame: frame) cardView.layer.cornerRadius = 16 layer.shadowColor = UIColor.black.cgColor layer.shadowRadius = 12 layer.shadowOpacity = 0.15 layer.shadowOffset = CGSize(width: 0, height: 8) addSubview(cardView) } override func layoutSubviews() { super.layoutSubviews() if cardView.superview == self { // this is necessary because we used `.useNoSnapshot` modifier on cardView. // we don't want cardView to be resized when Hero is using it for transition cardView.frame = bounds } layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath } override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) isTouched = true } override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) isTouched = false } override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) isTouched = false } } class AppStoreViewController1: ExampleBaseViewController { let collectionView = CollectionView() override func viewDidLoad() { super.viewDidLoad() collectionView.delaysContentTouches = false view.insertSubview(collectionView, belowSubview: dismissButton) setupCollection() } func setupCollection() { let dataSource = ArrayDataSource(data: Array(0..<10)) let viewSource = ClosureViewSource { (view: RoundedCardWrapperView, data: Int, index) in view.cardView.titleLabel.text = "Hero" view.cardView.subtitleLabel.text = "App Store Card Transition" view.cardView.imageView.image = UIImage(named: "Unsplash\(data)") } let sizeSource = { (i: Int, data: Int, size: CGSize) -> CGSize in return CGSize(width: size.width, height: size.width + 20) } let provider = BasicProvider( dataSource: dataSource, viewSource: viewSource, sizeSource: sizeSource, layout: FlowLayout(spacing: 30).inset(by: UIEdgeInsets(top: 100, left: 20, bottom: 30, right: 20)) ) provider.tapHandler = { (context) in self.cellTapped(cell: context.view, data: context.data) } collectionView.provider = provider } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() collectionView.frame = view.bounds } func cellTapped(cell: RoundedCardWrapperView, data: Int) { // MARK: Hero configuration let cardHeroId = "card\(data)" cell.cardView.hero.modifiers = [.useNoSnapshot, .spring(stiffness: 250, damping: 25)] cell.cardView.hero.id = cardHeroId let vc = AppStoreViewController2() vc.hero.isEnabled = true vc.hero.modalAnimationType = .none vc.cardView.hero.id = cardHeroId vc.cardView.hero.modifiers = [.useNoSnapshot, .spring(stiffness: 250, damping: 25)] vc.cardView.imageView.image = UIImage(named: "Unsplash\(data)") vc.contentCard.hero.modifiers = [.source(heroID: cardHeroId), .spring(stiffness: 250, damping: 25)] vc.contentView.hero.modifiers = [.useNoSnapshot, .forceAnimate, .spring(stiffness: 250, damping: 25)] vc.visualEffectView.hero.modifiers = [.fade, .useNoSnapshot] present(vc, animated: true, completion: nil) } } class AppStoreViewController2: ExampleBaseViewController { let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light)) let contentCard = UIView() let cardView = CardView() let contentView = UILabel() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear view.addSubview(visualEffectView) cardView.titleLabel.text = "Hero 2" cardView.subtitleLabel.text = "App Store Card Transition" contentView.numberOfLines = 0 contentView.text = """ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent neque est, hendrerit vitae nibh ultrices, accumsan elementum ante. Phasellus fringilla sapien non lorem consectetur, in ullamcorper tortor condimentum. Nulla tincidunt iaculis maximus. Sed ut urna urna. Nulla at sem vel neque scelerisque imperdiet. Donec ornare luctus dapibus. Donec aliquet ante augue, at pellentesque ipsum mollis eget. Cras vulputate mauris ac eleifend sollicitudin. Vivamus ut posuere odio. Suspendisse vulputate sem vel felis vehicula iaculis. Fusce sagittis, eros quis consequat tincidunt, arcu nunc ornare nulla, non egestas dolor ex at ipsum. Cras et massa sit amet quam imperdiet viverra. Mauris vitae finibus nibh, ac vulputate sapien. """ if #available(iOS 13.0, tvOS 13, *) { contentCard.backgroundColor = .systemBackground } else { contentCard.backgroundColor = .white } contentCard.clipsToBounds = true contentCard.addSubview(contentView) contentCard.addSubview(cardView) view.addSubview(contentCard) // add a pan gesture recognizer for the interactive dismiss transition view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(gr:)))) } @objc func handlePan(gr: UIPanGestureRecognizer) { let translation = gr.translation(in: view) switch gr.state { case .began: dismiss(animated: true, completion: nil) case .changed: Hero.shared.update(translation.y / view.bounds.height) default: let velocity = gr.velocity(in: view) if ((translation.y + velocity.y) / view.bounds.height) > 0.5 { Hero.shared.finish() } else { Hero.shared.cancel() } } } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let bounds = view.bounds visualEffectView.frame = bounds contentCard.frame = bounds cardView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.width) contentView.frame = CGRect(x: 20, y: bounds.width + 20, width: bounds.width - 40, height: bounds.height - bounds.width - 20) } } ================================================ FILE: Examples/BuiltInTransitionExample.swift ================================================ import UIKit import Hero /*: # Builtin transitions Hero has a few basic transition builtin. These can be used by setting `hero.modalAnimationType` to any ViewController that you want to present. These can be: ``` .none .push(direction: Direction) .pull(direction: Direction) .cover(direction: Direction) .uncover(direction: Direction) .slide(direction: Direction) .zoomSlide(direction: Direction) .pageIn(direction: Direction) .pageOut(direction: Direction) .fade .zoom .zoomOut ``` There are also three special ones * `.auto` is the default animation type. It uses the following animations depending on the presentation style: `.none` if source root view or destination root view have existing animations (defined via heroID or heroModifiers). `.push` & `.pull` if animating within a UINavigationController. `.slide` if animating within a UITabbarController. `.fade` if presenting modally. `.none` if presenting modally with modalPresentationStyle == .overFullScreen. * `.autoReverse(presenting: HeroDefaultAnimationType)` runs the given animation when presenting and runs the reverse animation when dismising. When not using .autoReverse, present and dismiss animation will be in the same direction. * `.selectBy(presenting: HeroDefaultAnimationType, dismissing: HeroDefaultAnimationType)` runs the given `presenting` animation during present and runs the `dismissing` animation during dismiss */ class BuiltInTransitionExampleViewController1: ExampleBaseViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor(hexString: "FC3A5E")! } @objc override func onTap() { let vc2 = BuiltInTransitionExampleViewController2() // this enables Hero vc2.hero.isEnabled = true // this configures the built in animation // vc2.hero.modalAnimationType = .zoom // vc2.hero.modalAnimationType = .pageIn(direction: .left) // vc2.hero.modalAnimationType = .pull(direction: .left) // vc2.hero.modalAnimationType = .autoReverse(presenting: .pageIn(direction: .left)) vc2.hero.modalAnimationType = .selectBy(presenting: .pull(direction: .left), dismissing: .slide(direction: .down)) // lastly, present the view controller like normal present(vc2, animated: true, completion: nil) } } class BuiltInTransitionExampleViewController2: ExampleBaseViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor(hexString: "555555")! } } ================================================ FILE: Examples/ExampleBaseViewController.swift ================================================ // // ExampleBaseViewController.swift // HeroExamples // // Created by Luke Zhao on 2018-04-15. // Copyright © 2018 Luke Zhao. All rights reserved. // import UIKit // basically a view controller with a back button and a tap gesture configured class ExampleBaseViewController: UIViewController { let dismissButton = UIButton(type: .system) override func viewDidLoad() { super.viewDidLoad() if #available(iOS 13.0, tvOS 13, *) { view.backgroundColor = .systemBackground } else { view.backgroundColor = .white } view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTap))) dismissButton.setTitle("Back", for: .normal) dismissButton.addTarget(self, action: #selector(back), for: .touchUpInside) dismissButton.hero.id = "back button" view.addSubview(dismissButton) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() dismissButton.sizeToFit() dismissButton.center = CGPoint(x: 30, y: 30) } @objc func back() { dismiss(animated: true, completion: nil) } @objc func onTap() { back() // default action is back on tap } } ================================================ FILE: Examples/MainViewController.swift ================================================ import UIKit import CollectionKit class MainViewController: UIViewController { typealias SourceData = (makeViewController: ()->(UIViewController), exampleTitle:String) let collectionView = CollectionView() override func viewDidLoad() { super.viewDidLoad() if #available(iOS 13.0, tvOS 13, *) { view.backgroundColor = UIColor.systemBackground } else { view.backgroundColor = .white } view.addSubview(collectionView) setupcollection() } func setupcollection() { let dataSource = ArrayDataSource(data: [ ({ BuiltInTransitionExampleViewController1() }, "Built In Animations"), ({ MatchExampleViewController1() }, "Match Animation"), ({ MatchInCollectionExampleViewController1() }, "Match Cell in Collection"), ({ AppStoreViewController1() }, "App Store Transition"), ]) if #available(iOS 13.0, *) { dataSource.data.insert(({ SwiftUIMatchExampleViewController() }, "Match SwiftUI"), at: 2) } let viewSource = ClosureViewSource { (label: UILabel, data: SourceData, index) in label.text = "\(index + 1). \(data.exampleTitle)" label.textAlignment = .center if #available(iOS 13.0, tvOS 13, *) { label.textColor = .label label.backgroundColor = .systemBackground } else { label.textColor = .darkText label.backgroundColor = .white } label.layer.borderColor = UIColor.gray.cgColor label.layer.borderWidth = 0.5 label.layer.cornerRadius = 8 } let sizeSource = { (i: Int, data: SourceData, size: CGSize) -> CGSize in return CGSize(width: size.width, height: 64) } let examplesProvider = BasicProvider( dataSource: dataSource, viewSource: viewSource, sizeSource: sizeSource, layout: FlowLayout(lineSpacing: 10)) { (context) in let vc = context.data.makeViewController() vc.modalPresentationStyle = .fullScreen self.present(vc, animated: true, completion: nil) } // TODO: Migrate the example to CollectionKit 2.2.0 let imageView = UIImageView(image: #imageLiteral(resourceName: "HeroLogo")) imageView.contentMode = .scaleAspectFit let imageProvider = SimpleViewProvider(views: [imageView], sizeStrategy: (.fill, .fit)) collectionView.provider = ComposedProvider( layout: FlowLayout(lineSpacing: 10).inset(by: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)), sections: [imageProvider, examplesProvider] ) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() collectionView.frame = view.bounds } } ================================================ FILE: Examples/MatchExample.swift ================================================ import UIKit /*: # Matching View Use `hero.id` to match views from one view controller to another view controller. Views that have the same hero.id will be automatically transitioned by Hero from its source state to its destination state. Use `hero.modifiers` to add extra animations or adjust how Hero handles the transition for that specific view. Check out `HeroModifiers.swift` for list of modifiers available. */ class MatchExampleViewController1: ExampleBaseViewController { let redView = UIView() let blackView = UIView() override func viewDidLoad() { super.viewDidLoad() redView.backgroundColor = UIColor(hexString: "FC3A5E")! redView.hero.id = "ironMan" redView.cornerRadius = 8 view.addSubview(redView) blackView.backgroundColor = UIColor(hexString: "555555")! blackView.hero.id = "batMan" blackView.cornerRadius = 8 view.addSubview(blackView) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() redView.frame.size = CGSize(width: 200, height: 200) blackView.frame.size = CGSize(width: 200, height: 80) redView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY + 50) blackView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY - 90) } @objc override func onTap() { let vc2 = MatchExampleViewController2() vc2.hero.isEnabled = true present(vc2, animated: true, completion: nil) } } class MatchExampleViewController2: ExampleBaseViewController { let redView = UIView() let blackView = UIView() let backgroundView = UIView() override func viewDidLoad() { super.viewDidLoad() redView.backgroundColor = UIColor(hexString: "FC3A5E")! redView.hero.id = "ironMan" view.insertSubview(redView, belowSubview: dismissButton) blackView.backgroundColor = UIColor(hexString: "555555")! blackView.hero.id = "batMan" blackView.cornerRadius = 8 view.addSubview(blackView) if #available(iOS 13.0, tvOS 13, *) { backgroundView.backgroundColor = .systemBackground } else { backgroundView.backgroundColor = .white } backgroundView.cornerRadius = 8 // .useGlobalCoordinateSpace modifier is needed here otherwise it will be covered by redView during transition. // see http://lkzhao.com/2018/03/02/hero-useglobalcoordinatespace-explained.html for detail backgroundView.hero.modifiers = [.translate(y: 500), .useGlobalCoordinateSpace] view.addSubview(backgroundView) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() redView.frame = view.bounds blackView.frame.size = CGSize(width: 250, height: 60) blackView.center = CGPoint(x: view.bounds.midX, y: 130) backgroundView.frame = CGRect(x: (view.bounds.width - 250) / 2, y: 180, width: 250, height: view.bounds.height - 320) } } ================================================ FILE: Examples/MatchInCollectionExample.swift ================================================ import UIKit import CollectionKit class MatchInCollectionExampleViewController1: ExampleBaseViewController { let collectionView = CollectionView() override func viewDidLoad() { super.viewDidLoad() view.insertSubview(collectionView, belowSubview: dismissButton) setupCollection() } func setupCollection() { let dataSource = ArrayDataSource(data: Array(0..<30)) let viewSource = ClosureViewSource { (view: UILabel, data: Int, index: Int) in let color = UIColor(hue: CGFloat(data) / 30, saturation: 0.68, brightness: 0.98, alpha: 1) view.backgroundColor = color view.textColor = .white view.textAlignment = .center view.layer.cornerRadius = 4 view.layer.masksToBounds = true view.text = "\(data)" } let sizeSource = { (i: Int, data: Int, size: CGSize) -> CGSize in let width: CGFloat = (size.width - 20) / 3 return CGSize(width: width, height: width) } let provider = BasicProvider( dataSource: dataSource, viewSource: viewSource, sizeSource: sizeSource, layout: FlowLayout(spacing: 10).inset(by: UIEdgeInsets(top: 100, left: 10, bottom: 10, right: 10)) ) provider.tapHandler = { (context) in self.cellTapped(cell: context.view, data: context.data) } collectionView.provider = provider } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() collectionView.frame = view.bounds } func cellTapped(cell: UIView, data: Int) { // MARK: Hero configuration // here we are using the data as the hero.id, we have to make sure that this id is // unique for each cell. a random hero.id will also work. let heroId = "cell\(data)" cell.hero.id = heroId let vc = MatchInCollectionExampleViewController2() vc.hero.isEnabled = true // copy over the backgroundColor and hero.id over to the next view // controller. In a real app, we would be passing some data correspoding to the cell // being tapped. then configure the next view controller according to the data. // and make sure that views that need to be transitioned have the same hero.id vc.contentView.backgroundColor = cell.backgroundColor vc.contentView.hero.id = heroId present(vc, animated: true, completion: nil) } } class MatchInCollectionExampleViewController2: ExampleBaseViewController { let contentView = UIView() override func viewDidLoad() { super.viewDidLoad() contentView.cornerRadius = 8 view.addSubview(contentView) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() contentView.frame = CGRect(x: (view.bounds.width - 250) / 2, y: 140, width: 250, height: view.bounds.height - 280) } } ================================================ FILE: Examples/Resources/AppDelegate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. window = UIWindow(frame: UIScreen.main.bounds) window!.rootViewController = MainViewController() window!.makeKeyAndVisible() return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } #if !(swift(>=4.2)) import CoreMedia extension UIApplication { typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey } func CMTimeMakeWithSeconds(_ seconds: Float64, preferredTimescale: Int32) -> CMTime { return CMTimeMakeWithSeconds(seconds, preferredTimescale) } extension CMTime { static let zero = kCMTimeZero } #endif ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Back@large.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json ================================================ { "layers" : [ { "filename" : "Front.imagestacklayer" }, { "filename" : "Middle.imagestacklayer" }, { "filename" : "Back.imagestacklayer" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Front@large.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Middle@large.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Back.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json ================================================ { "layers" : [ { "filename" : "Front.imagestacklayer" }, { "filename" : "Middle.imagestacklayer" }, { "filename" : "Back.imagestacklayer" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Front.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Middle.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json ================================================ { "assets" : [ { "size" : "1280x768", "idiom" : "tv", "filename" : "App Icon - Large.imagestack", "role" : "primary-app-icon" }, { "size" : "400x240", "idiom" : "tv", "filename" : "App Icon - Small.imagestack", "role" : "primary-app-icon" }, { "size" : "2320x720", "idiom" : "tv", "filename" : "Top Shelf Image Wide.imageset", "role" : "top-shelf-image-wide" }, { "size" : "1920x720", "idiom" : "tv", "filename" : "Top Shelf Image.imageset", "role" : "top-shelf-image" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Top Shelf Image Wide.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "filename" : "Top Shelf Image.png", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-20@2x.png", "scale" : "2x" }, { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-20@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-40@3x.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-60@3x.png", "scale" : "3x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-20.png", "scale" : "1x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-20@2x-1.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-29.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-29@2x-1.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-40.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-40@2x-1.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-76.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-76@2x.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "Icon-83.5@2x.png", "scale" : "2x" }, { "size" : "1024x1024", "idiom" : "ios-marketing", "filename" : "Icon-1024.png", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/AppleHomePage/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/AppleHomePage/iphone_alt_small_2x.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "iphone_alt_small_2x.jpg", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/AppleHomePage/macbookpro_portrait_small_2x.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "macbookpro_portrait_small_2x.jpg", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/AppleHomePage/watch_alt_portrait_small_2x.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "watch_alt_portrait_small_2x.jpg", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/CityGuide/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/CityGuide/cityGuide.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "316f8e75.jpeg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/CityGuide/montreal.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "photo-1419041082630-1e98debd0a6a.jpeg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/CityGuide/toronto.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "photo-1437147921639-ef00e030265a.jpeg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/CityGuide/vancouver.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "316f8e75.jpeg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash0.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash0.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash0_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash0_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash0_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash0_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash1.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash1.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash10.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash10.jpg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash10_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash10_cell.jpg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash10_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash10_thumb.jpg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash1_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash1_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash1_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash1_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash2.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash2.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash2_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash2_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash2_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash2_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash3.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash3.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash3_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash3_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash3_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash3_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash4.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash4.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash4_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash4_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash4_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash4_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash5.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash5.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash5_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash5_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash5_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash5_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash6.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash6.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash6_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash6_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash6_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash6_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash7.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash7.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash7_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash7_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash7_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash7_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash8.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash8.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash8_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash8_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash8_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash8_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash9.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash9.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash9_cell.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash9_cell.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Foods/Unsplash9_thumb.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "Unsplash9_thumb.png", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/HeroLogo.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "HeroLogo.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "HeroLogo@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "HeroLogo@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_audiotrack_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_audiotrack_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_audiotrack_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_audiotrack_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_chat_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_chat_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_chat_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_chat_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_format_quote_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_format_quote_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_format_quote_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_format_quote_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_gif_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_gif_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_gif_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_gif_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_insert_photo_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_insert_photo_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_insert_photo_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_insert_photo_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_link_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_link_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_link_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_link_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_menu_36pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_menu_36pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_menu_36pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_menu_36pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" }, "properties" : { "template-rendering-intent" : "template" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_menu_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_menu_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_menu_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_menu_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" }, "properties" : { "template-rendering-intent" : "template" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_text_fields_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_text_fields_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_text_fields_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_text_fields_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/Menu/ic_videocam_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_videocam_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_videocam_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_videocam_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/album1.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "computergraphics-album-covers-2014-3.jpg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/ic_fast_forward.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_fast_forward.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_fast_forward_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_fast_forward_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/ic_fast_rewind.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_fast_rewind.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_fast_rewind_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_fast_rewind_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/ic_pause_white.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_pause_white.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_pause_white_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_pause_white_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/ic_play_arrow_white.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_play_arrow_white.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_play_arrow_white_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_play_arrow_white_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/ic_repeat.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_repeat.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_repeat_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_repeat_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/MusicPlayer/ic_shuffle.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_shuffle.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_shuffle_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_shuffle_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/bigbuckbunny.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "poster.jpg", "scale" : "1x" }, { "idiom" : "universal", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_bug_report_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_bug_report_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_bug_report_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_bug_report_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_close.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_close.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_close_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_close_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_code.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_code.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_code_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_code_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_input_48pt.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_input_48pt.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_input_48pt_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_input_48pt_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_keyboard_arrow_down.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_keyboard_arrow_down.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_keyboard_arrow_down_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_keyboard_arrow_down_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_view_list.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_view_list.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_view_list_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_view_list_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Assets.xcassets/ic_view_module.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "ic_view_module.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "ic_view_module_2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "ic_view_module_3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Examples/Resources/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: Examples/Resources/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities armv7 UIRequiresFullScreen UIStatusBarHidden UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: Examples/Resources/UIKit+HeroExamples.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit public extension UIView { @IBInspectable var cornerRadius: CGFloat { get { return layer.cornerRadius } set { layer.cornerRadius = newValue } } @IBInspectable var shadowRadius: CGFloat { get { return layer.shadowRadius } set { layer.shadowRadius = newValue } } @IBInspectable var shadowOpacity: Float { get { return layer.shadowOpacity } set { layer.shadowOpacity = newValue } } @IBInspectable var shadowColor: UIColor? { get { return layer.shadowColor != nil ? UIColor(cgColor: layer.shadowColor!) : nil } set { layer.shadowColor = newValue?.cgColor } } @IBInspectable var shadowOffset: CGSize { get { return layer.shadowOffset } set { layer.shadowOffset = newValue } } @IBInspectable var zPosition: CGFloat { get { return layer.zPosition } set { layer.zPosition = newValue } } } func viewController(forStoryboardName: String) -> UIViewController { return UIStoryboard(name: forStoryboardName, bundle: nil).instantiateInitialViewController()! } class TemplateImageView: UIImageView { @IBInspectable var templateImage: UIImage? { didSet { image = templateImage?.withRenderingMode(.alwaysTemplate) } } } ================================================ FILE: Examples/SwiftUIMatchExample.swift ================================================ #if canImport(SwiftUI) import UIKit import SwiftUI import Hero @available(iOS 13.0, *) class SwiftUIMatchExampleViewController: UIHostingController { required init() { super.init(rootView: ImagesTableView()) rootView.dismiss = self.dismiss rootView.onTapRow = { image in let destinationViewController = UIHostingController(rootView: ImageViewWrapper(name: image.name, heroID: image.name) .onTapGesture { [weak self] in self?.presentedViewController?.dismiss(animated: true, completion: nil) }) destinationViewController.isHeroEnabled = true self.present(destinationViewController, animated: true, completion: nil) } } @objc required dynamic init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func dismiss(){ self.dismiss(animated: true, completion: nil) } } struct ImageInfo: Identifiable { let id: Int let name: String } @available(iOS 13.0, *) struct ImagesTableView: View { var dismiss: (() -> Void)? var onTapRow: ((ImageInfo)->())? @State var images = (0...9).map{ ImageInfo(id: $0, name: "Unsplash\($0)") } var body: some View { VStack { HStack{ Button(action: { self.dismiss?() }) { Text("Back") }.padding(.leading) Spacer() } List(images) { image in HStack { ImageViewWrapper(name: "\(image.name)_cell", heroID: image.name) Spacer() Text("Image number \(image.id)").padding() }.onTapGesture { self.onTapRow?(image) } } } } } @available(iOS 13.0, *) struct ImageViewWrapper: View, UIViewRepresentable { let name: String let heroID: String? func makeUIView(context: UIViewRepresentableContext) -> UIImageView { UIImageView(frame: .zero) } func updateUIView(_ uiView: UIImageView, context: UIViewRepresentableContext) { uiView.image = UIImage(named: name) uiView.hero.id = heroID } } //MARK: - Previews (Will only work when target of HeroExamples is set to iOS 13 +) #if DEBUG @available(iOS 13.0, *) struct ImagesTableView_Previews: PreviewProvider { static var previews: some View { ImagesTableView(onTapRow: nil) } } @available(iOS 13.0, *) struct ImageViewWrapper_Previews: PreviewProvider { static var previews: some View { ImageViewWrapper(name: "Unsplash0", heroID: nil) } } #endif #endif ================================================ FILE: Gemfile ================================================ # frozen_string_literal: true source 'https://rubygems.org' #ruby '~> 2.5.1' gem 'cocoapods', '~> 1.10' gem 'cocoapods-check' gem 'cocoapods-generate' gem 'cocoapods-githooks' # Sync .git-hooks across team members at `pod install` time gem 'cocoapods-packager' # Generate a framework or static library from a podspec. https://github.com/CocoaPods/cocoapods-packager gem 'cocoapods-repo-update' # Fixes issues with CI not updating specs # Temporary workaround for bug in binary file diffing # https://github.com/danger/danger/issues/1055 # https://github.com/ruby-git/ruby-git/pull/405 gem 'git', git: 'https://github.com/jcouball/ruby-git.git' gem 'fastlane' gem 'xcode-install' group :documentation do # gem 'jazzy', '~> 0.11' end group :test do gem 'git_diff_parser' gem 'xcpretty' gem 'danger' gem 'danger-auto_label' gem 'danger-swiftlint' # Danger plugin to validate the code coverage of the files changed # - Gem: danger-xcov # - URL: https://github.com/nakiostudio/danger-xcov gem 'danger-xcov' end plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path) ================================================ FILE: Hero.podspec ================================================ # frozen_string_literal: true Pod::Spec.new do |s| s.name = 'Hero' s.version = '1.6.4' s.summary = 'Elegant transition library for iOS' s.description = <<-DESC Hero is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit's cumbersome transition APIs. Making custom transitions an easy task for developers. DESC s.homepage = 'https://github.com/HeroTransitions/Hero' s.screenshots = 'https://github.com/HeroTransitions/Hero/blob/master/Resources/Hero.png?raw=true' s.documentation_url = 'https://herotransitions.github.io/Hero/' s.screenshots = ['https://git.io/JeRkv', 'https://git.io/JeRke', 'https://git.io/JeRkf', 'https://git.io/JeRkJ'] s.license = { :type => 'MIT' } s.author = { 'Luke' => 'lzhaoyilun@gmail.com', 'Joe Mattiello' => 'git@joemattiello.com' } s.source = { git: 'https://github.com/HeroTransitions/Hero.git', tag: s.version.to_s } s.cocoapods_version = '>= 1.4.0' s.ios.deployment_target = '10.0' s.tvos.deployment_target = '10.0' s.ios.frameworks = 'UIKit', 'Foundation', 'QuartzCore', 'CoreGraphics', 'CoreMedia' s.tvos.frameworks = 'UIKit', 'Foundation', 'QuartzCore', 'CoreGraphics', 'CoreMedia' s.swift_version = '5.0' s.requires_arc = true s.source_files = 'Sources/**/*.swift' end ================================================ FILE: Hero.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 1F0287FA2173F3C80008FA3B /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0287F92173F3C80008FA3B /* SwiftSupport.swift */; }; 1F0287FB2173F3C80008FA3B /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0287F92173F3C80008FA3B /* SwiftSupport.swift */; }; 2D1F7FC71E49DD02004D944B /* HeroTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B511E2C0CBD00AC1959 /* HeroTransition.swift */; }; 2D1F7FC81E49DD04004D944B /* HeroContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B521E2C0CBD00AC1959 /* HeroContext.swift */; }; 2D1F7FC91E49DD08004D944B /* HeroModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B551E2C0CBD00AC1959 /* HeroModifier.swift */; }; 2D1F7FCA1E49DD08004D944B /* HeroPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B561E2C0CBD00AC1959 /* HeroPlugin.swift */; }; 2D1F7FCB1E49DD08004D944B /* HeroTargetState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B571E2C0CBD00AC1959 /* HeroTargetState.swift */; }; 2D1F7FCC1E49DD08004D944B /* HeroTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B581E2C0CBD00AC1959 /* HeroTypes.swift */; }; 2D1F7FCD1E49DD13004D944B /* BasePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3298CD91E304851005B06BB /* BasePreprocessor.swift */; }; 2D1F7FCE1E49DD13004D944B /* CascadePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B3D1E2C0C7E00AC1959 /* CascadePreprocessor.swift */; }; 2D1F7FCF1E49DD13004D944B /* IgnoreSubviewModifiersPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B3E1E2C0C7E00AC1959 /* IgnoreSubviewModifiersPreprocessor.swift */; }; 2D1F7FD01E49DD13004D944B /* MatchPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B3F1E2C0C7E00AC1959 /* MatchPreprocessor.swift */; }; 2D1F7FD11E49DD13004D944B /* SourcePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B401E2C0C7E00AC1959 /* SourcePreprocessor.swift */; }; 2D1F7FD21E49DD18004D944B /* Array+HeroModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B451E2C0C9300AC1959 /* Array+HeroModifier.swift */; }; 2D1F7FD31E49DD18004D944B /* CALayer+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B461E2C0C9300AC1959 /* CALayer+Hero.swift */; }; 2D1F7FD41E49DD18004D944B /* CAMediaTimingFunction+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B471E2C0C9300AC1959 /* CAMediaTimingFunction+Hero.swift */; }; 2D1F7FD51E49DD18004D944B /* CG+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B481E2C0C9300AC1959 /* CG+Hero.swift */; }; 2D1F7FD61E49DD18004D944B /* DispatchQueue+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B491E2C0C9300AC1959 /* DispatchQueue+Hero.swift */; }; 2D1F7FD71E49DD18004D944B /* UIKit+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B4A1E2C0C9300AC1959 /* UIKit+Hero.swift */; }; 2D1F7FD81E49DD1D004D944B /* HeroDefaultAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B531E2C0CBD00AC1959 /* HeroDefaultAnimator.swift */; }; 2D1F7FD91E49DD1D004D944B /* HeroCoreAnimationViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B541E2C0CBD00AC1959 /* HeroCoreAnimationViewContext.swift */; }; 2D1F7FDA1E49DD21004D944B /* HeroDebugPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B611E2C0CD000AC1959 /* HeroDebugPlugin.swift */; }; 2D1F7FDB1E49DD21004D944B /* HeroDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B621E2C0CD100AC1959 /* HeroDebugView.swift */; }; 2D1F7FDC1E49DD3C004D944B /* Hero.h in Headers */ = {isa = PBXBuildFile; fileRef = A306D3B41E1C7A2E00B6C23A /* Hero.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2D1F7FE51E49DD90004D944B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1F7FE41E49DD90004D944B /* AppDelegate.swift */; }; 2D1F7FE71E49DD90004D944B /* TVImageGalleryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1F7FE61E49DD90004D944B /* TVImageGalleryViewController.swift */; }; 2D1F7FEA1E49DD90004D944B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2D1F7FE81E49DD90004D944B /* Main.storyboard */; }; 2D1F7FF21E49E043004D944B /* Hero.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D1F7FBF1E49DCB5004D944B /* Hero.framework */; }; 4D307DF420E3C6DC00DD9F65 /* HeroModifier+Advanced.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D307DF320E3C6DC00DD9F65 /* HeroModifier+Advanced.swift */; }; 4D307DF520E3C6DC00DD9F65 /* HeroModifier+Advanced.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D307DF320E3C6DC00DD9F65 /* HeroModifier+Advanced.swift */; }; 5C5442AA2004092500E1E326 /* HeroCompatible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C69728F2002CDBD001A5051 /* HeroCompatible.swift */; }; 5C6972902002CDBD001A5051 /* HeroCompatible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C69728F2002CDBD001A5051 /* HeroCompatible.swift */; }; 62EFDDAC236F4FC200F3E85E /* SwiftUIMatchExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EFDDAB236F4FC200F3E85E /* SwiftUIMatchExample.swift */; }; 83043017B73BC66DBB920D5C /* Pods_HeroExamples.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE340F89FF0A49DD23A5A6E /* Pods_HeroExamples.framework */; }; A306D3B61E1C7A2E00B6C23A /* Hero.h in Headers */ = {isa = PBXBuildFile; fileRef = A306D3B41E1C7A2E00B6C23A /* Hero.h */; settings = {ATTRIBUTES = (Public, ); }; }; A306D3B91E1C7A2E00B6C23A /* Hero.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A306D3B21E1C7A2E00B6C23A /* Hero.framework */; }; A306D3BB1E1C7A2E00B6C23A /* Hero.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A306D3B21E1C7A2E00B6C23A /* Hero.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; A3298CDA1E304851005B06BB /* BasePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3298CD91E304851005B06BB /* BasePreprocessor.swift */; }; A32D2CF21E4A7DC3008D35FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A33E60AB1DE761C90065CBD8 /* Assets.xcassets */; }; A32D2CFC1E4A80DC008D35FF /* UIKit+HeroExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33E60B61DE7621C0065CBD8 /* UIKit+HeroExamples.swift */; }; A32D2D021E4A8153008D35FF /* Basic.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A32D2D001E4A8153008D35FF /* Basic.storyboard */; }; A32D2D031E4A8153008D35FF /* ImageGallery.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A32D2D011E4A8153008D35FF /* ImageGallery.storyboard */; }; A32D2D051E4A81D5008D35FF /* ImageViewer.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A32D2D041E4A81D5008D35FF /* ImageViewer.storyboard */; }; A32D2D131E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = A32D2D121E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift */; }; A32D2D141E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = A32D2D121E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift */; }; A33E60A51DE761C90065CBD8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33E60A41DE761C90065CBD8 /* AppDelegate.swift */; }; A33E60AC1DE761C90065CBD8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A33E60AB1DE761C90065CBD8 /* Assets.xcassets */; }; A33E60AF1DE761C90065CBD8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A33E60AD1DE761C90065CBD8 /* LaunchScreen.storyboard */; }; A33E60BD1DE7621C0065CBD8 /* UIKit+HeroExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33E60B61DE7621C0065CBD8 /* UIKit+HeroExamples.swift */; }; A355CEC8D787CF71B0D7CBDA /* Pods_HeroTvOSExamples.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD2306FDA4E15ADA91EFED44 /* Pods_HeroTvOSExamples.framework */; }; A37D7B411E2C0C7E00AC1959 /* CascadePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B3D1E2C0C7E00AC1959 /* CascadePreprocessor.swift */; }; A37D7B421E2C0C7E00AC1959 /* IgnoreSubviewModifiersPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B3E1E2C0C7E00AC1959 /* IgnoreSubviewModifiersPreprocessor.swift */; }; A37D7B431E2C0C7E00AC1959 /* MatchPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B3F1E2C0C7E00AC1959 /* MatchPreprocessor.swift */; }; A37D7B441E2C0C7E00AC1959 /* SourcePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B401E2C0C7E00AC1959 /* SourcePreprocessor.swift */; }; A37D7B4B1E2C0C9300AC1959 /* Array+HeroModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B451E2C0C9300AC1959 /* Array+HeroModifier.swift */; }; A37D7B4C1E2C0C9300AC1959 /* CALayer+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B461E2C0C9300AC1959 /* CALayer+Hero.swift */; }; A37D7B4D1E2C0C9300AC1959 /* CAMediaTimingFunction+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B471E2C0C9300AC1959 /* CAMediaTimingFunction+Hero.swift */; }; A37D7B4E1E2C0C9300AC1959 /* CG+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B481E2C0C9300AC1959 /* CG+Hero.swift */; }; A37D7B4F1E2C0C9300AC1959 /* DispatchQueue+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B491E2C0C9300AC1959 /* DispatchQueue+Hero.swift */; }; A37D7B501E2C0C9300AC1959 /* UIKit+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B4A1E2C0C9300AC1959 /* UIKit+Hero.swift */; }; A37D7B591E2C0CBD00AC1959 /* HeroTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B511E2C0CBD00AC1959 /* HeroTransition.swift */; }; A37D7B5A1E2C0CBD00AC1959 /* HeroContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B521E2C0CBD00AC1959 /* HeroContext.swift */; }; A37D7B5B1E2C0CBD00AC1959 /* HeroDefaultAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B531E2C0CBD00AC1959 /* HeroDefaultAnimator.swift */; }; A37D7B5C1E2C0CBD00AC1959 /* HeroCoreAnimationViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B541E2C0CBD00AC1959 /* HeroCoreAnimationViewContext.swift */; }; A37D7B5D1E2C0CBD00AC1959 /* HeroModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B551E2C0CBD00AC1959 /* HeroModifier.swift */; }; A37D7B5E1E2C0CBD00AC1959 /* HeroPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B561E2C0CBD00AC1959 /* HeroPlugin.swift */; }; A37D7B5F1E2C0CBD00AC1959 /* HeroTargetState.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B571E2C0CBD00AC1959 /* HeroTargetState.swift */; }; A37D7B601E2C0CBD00AC1959 /* HeroTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B581E2C0CBD00AC1959 /* HeroTypes.swift */; }; A37D7B631E2C0CD100AC1959 /* HeroDebugPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B611E2C0CD000AC1959 /* HeroDebugPlugin.swift */; }; A37D7B641E2C0CD100AC1959 /* HeroDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A37D7B621E2C0CD100AC1959 /* HeroDebugView.swift */; }; A3B8C5672083376100E112F6 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3B8C5662083376100E112F6 /* MainViewController.swift */; }; A3D060C020833B0800E48927 /* BuiltInTransitionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3D060BF20833B0700E48927 /* BuiltInTransitionExample.swift */; }; A3D060C220833B4E00E48927 /* ExampleBaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3D060C120833B4E00E48927 /* ExampleBaseViewController.swift */; }; A3D060C420833D0400E48927 /* MatchExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3D060C320833D0400E48927 /* MatchExample.swift */; }; A3D060C6208348CB00E48927 /* MatchInCollectionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3D060C5208348CB00E48927 /* MatchInCollectionExample.swift */; }; A3D060C820834FF100E48927 /* AppStoreCardExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3D060C720834FF100E48927 /* AppStoreCardExample.swift */; }; AF1E1B541E66822C00ECE039 /* HeroTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF1E1B531E66822C00ECE039 /* HeroTests.swift */; }; AF6D934A1E65168D00FCD55E /* HeroStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF6D93491E65168D00FCD55E /* HeroStringConvertible.swift */; }; AF6D934B1E65168D00FCD55E /* HeroStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF6D93491E65168D00FCD55E /* HeroStringConvertible.swift */; }; AFA306CA1E6B446C00CAF719 /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C61E6B446C00CAF719 /* Lexer.swift */; }; AFA306CB1E6B446C00CAF719 /* Lexer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C61E6B446C00CAF719 /* Lexer.swift */; }; AFA306CC1E6B446C00CAF719 /* Nodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C71E6B446C00CAF719 /* Nodes.swift */; }; AFA306CD1E6B446C00CAF719 /* Nodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C71E6B446C00CAF719 /* Nodes.swift */; }; AFA306CE1E6B446C00CAF719 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C81E6B446C00CAF719 /* Parser.swift */; }; AFA306CF1E6B446C00CAF719 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C81E6B446C00CAF719 /* Parser.swift */; }; AFA306D01E6B446C00CAF719 /* Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C91E6B446C00CAF719 /* Regex.swift */; }; AFA306D11E6B446C00CAF719 /* Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA306C91E6B446C00CAF719 /* Regex.swift */; }; B101B2CB1E56140A007E7112 /* UIView+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = B101B2C91E561408007E7112 /* UIView+Hero.swift */; }; B101B2CC1E56140B007E7112 /* UIView+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = B101B2C91E561408007E7112 /* UIView+Hero.swift */; }; B101B2CE1E561421007E7112 /* UIViewController+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = B101B2CD1E561421007E7112 /* UIViewController+Hero.swift */; }; B101B2CF1E561421007E7112 /* UIViewController+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = B101B2CD1E561421007E7112 /* UIViewController+Hero.swift */; }; B1193AB61E525CD8005B1C87 /* HeroViewPropertyViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1193AB51E525CD8005B1C87 /* HeroViewPropertyViewContext.swift */; }; B1193AB71E525CD8005B1C87 /* HeroViewPropertyViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1193AB51E525CD8005B1C87 /* HeroViewPropertyViewContext.swift */; }; B1193AB91E525D12005B1C87 /* HeroAnimatorViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1193AB81E525D12005B1C87 /* HeroAnimatorViewContext.swift */; }; B1193ABA1E525D12005B1C87 /* HeroAnimatorViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1193AB81E525D12005B1C87 /* HeroAnimatorViewContext.swift */; }; B16197E01EF451C500A540D2 /* HeroTransition+Interactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16197DF1EF451C400A540D2 /* HeroTransition+Interactive.swift */; }; B16197E11EF451C500A540D2 /* HeroTransition+Interactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16197DF1EF451C400A540D2 /* HeroTransition+Interactive.swift */; }; B16B75311EF45A110018DBEF /* HeroTransitionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16B75301EF45A110018DBEF /* HeroTransitionState.swift */; }; B16B75321EF45A110018DBEF /* HeroTransitionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16B75301EF45A110018DBEF /* HeroTransitionState.swift */; }; B16B75341EF461090018DBEF /* HeroProgressRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16B75331EF461090018DBEF /* HeroProgressRunner.swift */; }; B16B75351EF461090018DBEF /* HeroProgressRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16B75331EF461090018DBEF /* HeroProgressRunner.swift */; }; B16ECD031E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16ECD021E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift */; }; B16ECD041E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16ECD021E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift */; }; B17D88861EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17D88851EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift */; }; B17D88871EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17D88851EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift */; }; B17D88891EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17D88881EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift */; }; B17D888A1EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17D88881EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift */; }; B17D888C1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17D888B1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift */; }; B17D888D1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17D888B1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift */; }; B1D816DF1EF5A5DF007B9776 /* HeroViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816DE1EF5A5DF007B9776 /* HeroViewControllerDelegate.swift */; }; B1D816E01EF5A5DF007B9776 /* HeroViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816DE1EF5A5DF007B9776 /* HeroViewControllerDelegate.swift */; }; B1D816E21EF5A630007B9776 /* HeroTransition+CustomTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816E11EF5A630007B9776 /* HeroTransition+CustomTransition.swift */; }; B1D816E31EF5A630007B9776 /* HeroTransition+CustomTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816E11EF5A630007B9776 /* HeroTransition+CustomTransition.swift */; }; B1D816E51EF5A6AE007B9776 /* HeroTransition+Start.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816E41EF5A6AE007B9776 /* HeroTransition+Start.swift */; }; B1D816E61EF5A6AE007B9776 /* HeroTransition+Start.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816E41EF5A6AE007B9776 /* HeroTransition+Start.swift */; }; B1D816E81EF5A6FE007B9776 /* HeroTransition+Complete.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816E71EF5A6FE007B9776 /* HeroTransition+Complete.swift */; }; B1D816E91EF5A6FE007B9776 /* HeroTransition+Complete.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816E71EF5A6FE007B9776 /* HeroTransition+Complete.swift */; }; B1D816EB1EF5A720007B9776 /* HeroTransition+Animate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816EA1EF5A720007B9776 /* HeroTransition+Animate.swift */; }; B1D816EC1EF5A720007B9776 /* HeroTransition+Animate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D816EA1EF5A720007B9776 /* HeroTransition+Animate.swift */; }; B1D834041F02E7C0009E1E36 /* ConditionalPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D834031F02E7C0009E1E36 /* ConditionalPreprocessor.swift */; }; B1D834051F02E7C0009E1E36 /* ConditionalPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D834031F02E7C0009E1E36 /* ConditionalPreprocessor.swift */; }; B35264CE2454FEF300D33861 /* Locale+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = B35264CD2454FEF300D33861 /* Locale+Hero.swift */; }; B35264CF2454FEF300D33861 /* Locale+Hero.swift in Sources */ = {isa = PBXBuildFile; fileRef = B35264CD2454FEF300D33861 /* Locale+Hero.swift */; }; B383074925D1041A00B7A0D8 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B383074825D1041A00B7A0D8 /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; B383074B25D1042C00B7A0D8 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B383074A25D1042C00B7A0D8 /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DBA05BB41A704A4A17967918 /* Pods_HeroTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841FFA357ACB279D3F74CDEE /* Pods_HeroTests.framework */; }; F482F0BE235D7808002E97ED /* UIColor+HexString.swift in Sources */ = {isa = PBXBuildFile; fileRef = F482F0BD235D7808002E97ED /* UIColor+HexString.swift */; }; F482F0BF235D7808002E97ED /* UIColor+HexString.swift in Sources */ = {isa = PBXBuildFile; fileRef = F482F0BD235D7808002E97ED /* UIColor+HexString.swift */; }; F482F0C0235D7A3A002E97ED /* ImageGalleryCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3499D9E1DF2024E0049B541 /* ImageGalleryCollectionViewController.swift */; }; F482F0C1235D7A51002E97ED /* ImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A304BF831DF2717900A03345 /* ImageViewController.swift */; }; F482F0C2235D7A5B002E97ED /* ImageCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = A304BF891DF647FC00A03345 /* ImageCells.swift */; }; F482F0C3235D7A65002E97ED /* ImageLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = A313499A1E1E2AED00EB5139 /* ImageLibrary.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 2D1F7FF31E49E05A004D944B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = A33E60991DE761C90065CBD8 /* Project object */; proxyType = 1; remoteGlobalIDString = 2D1F7FBE1E49DCB5004D944B; remoteInfo = "Hero (tvOS)"; }; A306D3B71E1C7A2E00B6C23A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = A33E60991DE761C90065CBD8 /* Project object */; proxyType = 1; remoteGlobalIDString = A306D3B11E1C7A2E00B6C23A; remoteInfo = Hero; }; AF1E1B561E66822C00ECE039 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = A33E60991DE761C90065CBD8 /* Project object */; proxyType = 1; remoteGlobalIDString = A33E60A01DE761C90065CBD8; remoteInfo = HeroExamples; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ A306D3BA1E1C7A2E00B6C23A /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( A306D3BB1E1C7A2E00B6C23A /* Hero.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 1F0287F92173F3C80008FA3B /* SwiftSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftSupport.swift; sourceTree = ""; }; 2D1F7FBF1E49DCB5004D944B /* Hero.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Hero.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2D1F7FE21E49DD90004D944B /* HeroTvOSExamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HeroTvOSExamples.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2D1F7FE41E49DD90004D944B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 2D1F7FE61E49DD90004D944B /* TVImageGalleryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TVImageGalleryViewController.swift; sourceTree = ""; }; 2D1F7FE91E49DD90004D944B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 2D1F7FED1E49DD90004D944B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4D307DF320E3C6DC00DD9F65 /* HeroModifier+Advanced.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroModifier+Advanced.swift"; sourceTree = ""; }; 5C69728F2002CDBD001A5051 /* HeroCompatible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroCompatible.swift; sourceTree = ""; }; 5CD4F09A588E81DA75C2BE38 /* Pods-HeroExamples.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HeroExamples.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HeroExamples/Pods-HeroExamples.debug.xcconfig"; sourceTree = ""; }; 5CEC69C9A9A60129002FD931 /* Pods-HeroTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HeroTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-HeroTests/Pods-HeroTests.release.xcconfig"; sourceTree = ""; }; 62EFDDAB236F4FC200F3E85E /* SwiftUIMatchExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIMatchExample.swift; sourceTree = ""; }; 841FFA357ACB279D3F74CDEE /* Pods_HeroTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HeroTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 86C87C73D89E75C8443B5071 /* Pods-HeroTvOSExamples.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HeroTvOSExamples.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HeroTvOSExamples/Pods-HeroTvOSExamples.debug.xcconfig"; sourceTree = ""; }; A304BF831DF2717900A03345 /* ImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageViewController.swift; sourceTree = ""; }; A304BF891DF647FC00A03345 /* ImageCells.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCells.swift; sourceTree = ""; }; A306D3B21E1C7A2E00B6C23A /* Hero.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Hero.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A306D3B41E1C7A2E00B6C23A /* Hero.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Hero.h; sourceTree = ""; }; A306D3B51E1C7A2E00B6C23A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A313499A1E1E2AED00EB5139 /* ImageLibrary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLibrary.swift; sourceTree = ""; }; A3298CD91E304851005B06BB /* BasePreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasePreprocessor.swift; sourceTree = ""; }; A32D2D001E4A8153008D35FF /* Basic.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Basic.storyboard; sourceTree = ""; }; A32D2D011E4A8153008D35FF /* ImageGallery.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ImageGallery.storyboard; sourceTree = ""; }; A32D2D041E4A81D5008D35FF /* ImageViewer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ImageViewer.storyboard; sourceTree = ""; }; A32D2D0C1E4D545B008D35FF /* MenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = ""; }; A32D2D0F1E4E14DD008D35FF /* BuiltInTransitions.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = BuiltInTransitions.storyboard; sourceTree = ""; }; A32D2D121E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "HeroModifier+HeroStringConvertible.swift"; sourceTree = ""; }; A33E60A11DE761C90065CBD8 /* HeroExamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HeroExamples.app; sourceTree = BUILT_PRODUCTS_DIR; }; A33E60A41DE761C90065CBD8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; A33E60A91DE761C90065CBD8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; A33E60AB1DE761C90065CBD8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; A33E60AE1DE761C90065CBD8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; A33E60B01DE761C90065CBD8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A33E60B61DE7621C0065CBD8 /* UIKit+HeroExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIKit+HeroExamples.swift"; sourceTree = ""; }; A33E60B91DE7621C0065CBD8 /* City.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = City.swift; sourceTree = ""; }; A33E60BA1DE7621C0065CBD8 /* CityGuideCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CityGuideCell.swift; sourceTree = ""; }; A33E60BB1DE7621C0065CBD8 /* CityGuideViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CityGuideViewController.swift; sourceTree = ""; }; A33E60BC1DE7621C0065CBD8 /* CityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CityViewController.swift; sourceTree = ""; }; A3499D9E1DF2024E0049B541 /* ImageGalleryCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageGalleryCollectionViewController.swift; sourceTree = ""; }; A35949171E1A2BE60095F407 /* LegacyExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyExampleViewController.swift; sourceTree = ""; }; A37D7B3D1E2C0C7E00AC1959 /* CascadePreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CascadePreprocessor.swift; sourceTree = ""; }; A37D7B3E1E2C0C7E00AC1959 /* IgnoreSubviewModifiersPreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IgnoreSubviewModifiersPreprocessor.swift; sourceTree = ""; }; A37D7B3F1E2C0C7E00AC1959 /* MatchPreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatchPreprocessor.swift; sourceTree = ""; }; A37D7B401E2C0C7E00AC1959 /* SourcePreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourcePreprocessor.swift; sourceTree = ""; }; A37D7B451E2C0C9300AC1959 /* Array+HeroModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+HeroModifier.swift"; sourceTree = ""; }; A37D7B461E2C0C9300AC1959 /* CALayer+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CALayer+Hero.swift"; sourceTree = ""; }; A37D7B471E2C0C9300AC1959 /* CAMediaTimingFunction+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CAMediaTimingFunction+Hero.swift"; sourceTree = ""; }; A37D7B481E2C0C9300AC1959 /* CG+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CG+Hero.swift"; sourceTree = ""; }; A37D7B491E2C0C9300AC1959 /* DispatchQueue+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+Hero.swift"; sourceTree = ""; }; A37D7B4A1E2C0C9300AC1959 /* UIKit+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIKit+Hero.swift"; sourceTree = ""; }; A37D7B511E2C0CBD00AC1959 /* HeroTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroTransition.swift; sourceTree = ""; }; A37D7B521E2C0CBD00AC1959 /* HeroContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroContext.swift; sourceTree = ""; }; A37D7B531E2C0CBD00AC1959 /* HeroDefaultAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroDefaultAnimator.swift; sourceTree = ""; }; A37D7B541E2C0CBD00AC1959 /* HeroCoreAnimationViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroCoreAnimationViewContext.swift; sourceTree = ""; }; A37D7B551E2C0CBD00AC1959 /* HeroModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroModifier.swift; sourceTree = ""; }; A37D7B561E2C0CBD00AC1959 /* HeroPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroPlugin.swift; sourceTree = ""; }; A37D7B571E2C0CBD00AC1959 /* HeroTargetState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroTargetState.swift; sourceTree = ""; }; A37D7B581E2C0CBD00AC1959 /* HeroTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroTypes.swift; sourceTree = ""; }; A37D7B611E2C0CD000AC1959 /* HeroDebugPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroDebugPlugin.swift; sourceTree = ""; }; A37D7B621E2C0CD100AC1959 /* HeroDebugView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroDebugView.swift; sourceTree = ""; }; A3B8C5662083376100E112F6 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; A3D060BF20833B0700E48927 /* BuiltInTransitionExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuiltInTransitionExample.swift; sourceTree = ""; }; A3D060C120833B4E00E48927 /* ExampleBaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleBaseViewController.swift; sourceTree = ""; }; A3D060C320833D0400E48927 /* MatchExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchExample.swift; sourceTree = ""; }; A3D060C5208348CB00E48927 /* MatchInCollectionExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchInCollectionExample.swift; sourceTree = ""; }; A3D060C720834FF100E48927 /* AppStoreCardExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreCardExample.swift; sourceTree = ""; }; A41D45F75C2C4244CC105281 /* Pods-HeroTvOSExamples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HeroTvOSExamples.release.xcconfig"; path = "Pods/Target Support Files/Pods-HeroTvOSExamples/Pods-HeroTvOSExamples.release.xcconfig"; sourceTree = ""; }; AF1E1B511E66822C00ECE039 /* HeroTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HeroTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; AF1E1B531E66822C00ECE039 /* HeroTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroTests.swift; sourceTree = ""; }; AF1E1B551E66822C00ECE039 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; AF6D93491E65168D00FCD55E /* HeroStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroStringConvertible.swift; sourceTree = ""; }; AFA306C61E6B446C00CAF719 /* Lexer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lexer.swift; sourceTree = ""; }; AFA306C71E6B446C00CAF719 /* Nodes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Nodes.swift; sourceTree = ""; }; AFA306C81E6B446C00CAF719 /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = ""; }; AFA306C91E6B446C00CAF719 /* Regex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Regex.swift; sourceTree = ""; }; B101B2C91E561408007E7112 /* UIView+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Hero.swift"; sourceTree = ""; }; B101B2CD1E561421007E7112 /* UIViewController+Hero.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Hero.swift"; sourceTree = ""; }; B114B68F1E412A0B0009CEDE /* AppleProductViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleProductViewController.swift; sourceTree = ""; }; B1193AB51E525CD8005B1C87 /* HeroViewPropertyViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroViewPropertyViewContext.swift; sourceTree = ""; wrapsLines = 1; }; B1193AB81E525D12005B1C87 /* HeroAnimatorViewContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeroAnimatorViewContext.swift; sourceTree = ""; }; B1275D961E4C0D850099A0E9 /* PluginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PluginViewController.swift; sourceTree = ""; }; B147F2631FAEA8F0006475A3 /* FirstViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = ""; }; B147F2641FAEA8F0006475A3 /* Navigation.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Navigation.storyboard; sourceTree = ""; }; B16197DF1EF451C400A540D2 /* HeroTransition+Interactive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "HeroTransition+Interactive.swift"; sourceTree = ""; }; B16A219F1E4E3907007B8B4C /* AnimationSelectTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationSelectTableViewController.swift; sourceTree = ""; }; B16B75301EF45A110018DBEF /* HeroTransitionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroTransitionState.swift; sourceTree = ""; }; B16B75331EF461090018DBEF /* HeroProgressRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroProgressRunner.swift; sourceTree = ""; }; B16ECD021E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultAnimationPreprocessor.swift; sourceTree = ""; }; B17D88851EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+UITabBarControllerDelegate.swift"; sourceTree = ""; }; B17D88881EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+UINavigationControllerDelegate.swift"; sourceTree = ""; }; B17D888B1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+UIViewControllerTransitioningDelegate.swift"; sourceTree = ""; }; B185A4E51DFA6E0C00C3B85D /* ListTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTableViewController.swift; sourceTree = ""; }; B185A4E71DFA6FE200C3B85D /* GridCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GridCollectionViewController.swift; sourceTree = ""; }; B19F76981E46C38E002DBC58 /* AppleHomePage.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = AppleHomePage.storyboard; sourceTree = ""; }; B19F769A1E46C3A2002DBC58 /* Basic.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Basic.storyboard; sourceTree = ""; }; B19F769B1E46C3A2002DBC58 /* Menu.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Menu.storyboard; sourceTree = ""; }; B19F769C1E46C3A2002DBC58 /* MusicPlayer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MusicPlayer.storyboard; sourceTree = ""; }; B19F76A01E46C3C2002DBC58 /* CityGuide.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = CityGuide.storyboard; sourceTree = ""; }; B19F76A21E46C3CB002DBC58 /* ListToGrid.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ListToGrid.storyboard; sourceTree = ""; }; B19F76A41E46C3D7002DBC58 /* ImageGallery.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ImageGallery.storyboard; sourceTree = ""; }; B19F76A51E46C3D7002DBC58 /* ImageViewer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ImageViewer.storyboard; sourceTree = ""; }; B19F76AF1E46C449002DBC58 /* VideoPlayer.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = VideoPlayer.storyboard; sourceTree = ""; }; B19F76B01E46C449002DBC58 /* VideoPlayerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerViewController.swift; sourceTree = ""; }; B1D816DE1EF5A5DF007B9776 /* HeroViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeroViewControllerDelegate.swift; sourceTree = ""; }; B1D816E11EF5A630007B9776 /* HeroTransition+CustomTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+CustomTransition.swift"; sourceTree = ""; }; B1D816E41EF5A6AE007B9776 /* HeroTransition+Start.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+Start.swift"; sourceTree = ""; }; B1D816E71EF5A6FE007B9776 /* HeroTransition+Complete.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+Complete.swift"; sourceTree = ""; }; B1D816EA1EF5A720007B9776 /* HeroTransition+Animate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HeroTransition+Animate.swift"; sourceTree = ""; }; B1D834031F02E7C0009E1E36 /* ConditionalPreprocessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConditionalPreprocessor.swift; sourceTree = ""; }; B35264CD2454FEF300D33861 /* Locale+Hero.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Locale+Hero.swift"; sourceTree = ""; }; B383074825D1041A00B7A0D8 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; B383074A25D1042C00B7A0D8 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.3.sdk/System/Library/Frameworks/SwiftUI.framework; sourceTree = DEVELOPER_DIR; }; C377744CBFF1E24426E80F55 /* Pods-HeroExamples.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HeroExamples.release.xcconfig"; path = "Pods/Target Support Files/Pods-HeroExamples/Pods-HeroExamples.release.xcconfig"; sourceTree = ""; }; C51A6465EC2CB38D82F28B93 /* Pods-HeroTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HeroTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HeroTests/Pods-HeroTests.debug.xcconfig"; sourceTree = ""; }; EEE340F89FF0A49DD23A5A6E /* Pods_HeroExamples.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HeroExamples.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F482F0BD235D7808002E97ED /* UIColor+HexString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+HexString.swift"; sourceTree = ""; }; F482F0C5235D7C4C002E97ED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; }; FD2306FDA4E15ADA91EFED44 /* Pods_HeroTvOSExamples.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HeroTvOSExamples.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2D1F7FBB1E49DCB5004D944B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 2D1F7FDF1E49DD90004D944B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 2D1F7FF21E49E043004D944B /* Hero.framework in Frameworks */, B383074B25D1042C00B7A0D8 /* SwiftUI.framework in Frameworks */, A355CEC8D787CF71B0D7CBDA /* Pods_HeroTvOSExamples.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; A306D3AE1E1C7A2E00B6C23A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; A33E609E1DE761C90065CBD8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( A306D3B91E1C7A2E00B6C23A /* Hero.framework in Frameworks */, B383074925D1041A00B7A0D8 /* SwiftUI.framework in Frameworks */, 83043017B73BC66DBB920D5C /* Pods_HeroExamples.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; AF1E1B4E1E66822C00ECE039 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( DBA05BB41A704A4A17967918 /* Pods_HeroTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 0ED3C727BC790F37EE7BD698 /* Frameworks */ = { isa = PBXGroup; children = ( B383074825D1041A00B7A0D8 /* SwiftUI.framework */, B383074A25D1042C00B7A0D8 /* SwiftUI.framework */, EEE340F89FF0A49DD23A5A6E /* Pods_HeroExamples.framework */, FD2306FDA4E15ADA91EFED44 /* Pods_HeroTvOSExamples.framework */, 841FFA357ACB279D3F74CDEE /* Pods_HeroTests.framework */, ); name = Frameworks; sourceTree = ""; }; 29FF2D9C1E21ACF400EA4E65 /* Extensions */ = { isa = PBXGroup; children = ( A37D7B451E2C0C9300AC1959 /* Array+HeroModifier.swift */, A37D7B461E2C0C9300AC1959 /* CALayer+Hero.swift */, A37D7B471E2C0C9300AC1959 /* CAMediaTimingFunction+Hero.swift */, A37D7B481E2C0C9300AC1959 /* CG+Hero.swift */, A37D7B491E2C0C9300AC1959 /* DispatchQueue+Hero.swift */, B35264CD2454FEF300D33861 /* Locale+Hero.swift */, A37D7B4A1E2C0C9300AC1959 /* UIKit+Hero.swift */, B101B2C91E561408007E7112 /* UIView+Hero.swift */, B101B2CD1E561421007E7112 /* UIViewController+Hero.swift */, F482F0BD235D7808002E97ED /* UIColor+HexString.swift */, ); path = Extensions; sourceTree = ""; }; 29FF2D9D1E21AD8900EA4E65 /* Preprocessors */ = { isa = PBXGroup; children = ( A3298CD91E304851005B06BB /* BasePreprocessor.swift */, A37D7B3D1E2C0C7E00AC1959 /* CascadePreprocessor.swift */, B16ECD021E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift */, A37D7B3E1E2C0C7E00AC1959 /* IgnoreSubviewModifiersPreprocessor.swift */, B1D834031F02E7C0009E1E36 /* ConditionalPreprocessor.swift */, A37D7B3F1E2C0C7E00AC1959 /* MatchPreprocessor.swift */, A37D7B401E2C0C7E00AC1959 /* SourcePreprocessor.swift */, ); path = Preprocessors; sourceTree = ""; }; 29FF2D9E1E21AD9E00EA4E65 /* Debug Plugin */ = { isa = PBXGroup; children = ( A37D7B611E2C0CD000AC1959 /* HeroDebugPlugin.swift */, A37D7B621E2C0CD100AC1959 /* HeroDebugView.swift */, ); path = "Debug Plugin"; sourceTree = ""; }; 29FF2D9F1E21ADB300EA4E65 /* Animator */ = { isa = PBXGroup; children = ( B1193AB81E525D12005B1C87 /* HeroAnimatorViewContext.swift */, A37D7B541E2C0CBD00AC1959 /* HeroCoreAnimationViewContext.swift */, A37D7B531E2C0CBD00AC1959 /* HeroDefaultAnimator.swift */, B1193AB51E525CD8005B1C87 /* HeroViewPropertyViewContext.swift */, ); path = Animator; sourceTree = ""; }; 2D1F7FE31E49DD90004D944B /* TvOSExamples */ = { isa = PBXGroup; children = ( 2D1F7FE41E49DD90004D944B /* AppDelegate.swift */, A32D2D001E4A8153008D35FF /* Basic.storyboard */, A32D2D011E4A8153008D35FF /* ImageGallery.storyboard */, A32D2D041E4A81D5008D35FF /* ImageViewer.storyboard */, 2D1F7FED1E49DD90004D944B /* Info.plist */, 2D1F7FE81E49DD90004D944B /* Main.storyboard */, 2D1F7FE61E49DD90004D944B /* TVImageGalleryViewController.swift */, ); path = TvOSExamples; sourceTree = ""; }; 46383DC6A22A87056E5B40EC /* Pods */ = { isa = PBXGroup; children = ( 5CD4F09A588E81DA75C2BE38 /* Pods-HeroExamples.debug.xcconfig */, C377744CBFF1E24426E80F55 /* Pods-HeroExamples.release.xcconfig */, 86C87C73D89E75C8443B5071 /* Pods-HeroTvOSExamples.debug.xcconfig */, A41D45F75C2C4244CC105281 /* Pods-HeroTvOSExamples.release.xcconfig */, C51A6465EC2CB38D82F28B93 /* Pods-HeroTests.debug.xcconfig */, 5CEC69C9A9A60129002FD931 /* Pods-HeroTests.release.xcconfig */, ); name = Pods; sourceTree = ""; }; A306D3B31E1C7A2E00B6C23A /* Sources */ = { isa = PBXGroup; children = ( 29FF2D9F1E21ADB300EA4E65 /* Animator */, 29FF2D9E1E21AD9E00EA4E65 /* Debug Plugin */, 29FF2D9C1E21ACF400EA4E65 /* Extensions */, AFA306D21E6B447200CAF719 /* Parser */, 29FF2D9D1E21AD8900EA4E65 /* Preprocessors */, B11769D81EF8626C00A1373A /* Transition */, A306D3B41E1C7A2E00B6C23A /* Hero.h */, 5C69728F2002CDBD001A5051 /* HeroCompatible.swift */, A37D7B521E2C0CBD00AC1959 /* HeroContext.swift */, A32D2D121E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift */, A37D7B551E2C0CBD00AC1959 /* HeroModifier.swift */, 4D307DF320E3C6DC00DD9F65 /* HeroModifier+Advanced.swift */, A37D7B561E2C0CBD00AC1959 /* HeroPlugin.swift */, A37D7B571E2C0CBD00AC1959 /* HeroTargetState.swift */, A37D7B581E2C0CBD00AC1959 /* HeroTypes.swift */, B1D816DE1EF5A5DF007B9776 /* HeroViewControllerDelegate.swift */, 1F0287F92173F3C80008FA3B /* SwiftSupport.swift */, A306D3B51E1C7A2E00B6C23A /* Info.plist */, ); path = Sources; sourceTree = ""; }; A32D2D0E1E4D5463008D35FF /* Menu */ = { isa = PBXGroup; children = ( B19F769B1E46C3A2002DBC58 /* Menu.storyboard */, A32D2D0C1E4D545B008D35FF /* MenuViewController.swift */, ); path = Menu; sourceTree = ""; }; A32D2D111E4E9899008D35FF /* BuiltInTransition */ = { isa = PBXGroup; children = ( B16A219F1E4E3907007B8B4C /* AnimationSelectTableViewController.swift */, A32D2D0F1E4E14DD008D35FF /* BuiltInTransitions.storyboard */, ); path = BuiltInTransition; sourceTree = ""; }; A33E60981DE761C90065CBD8 = { isa = PBXGroup; children = ( A306D3B31E1C7A2E00B6C23A /* Sources */, A3B8C5682083376C00E112F6 /* Examples */, A33E60A31DE761C90065CBD8 /* LegacyExamples */, 0ED3C727BC790F37EE7BD698 /* Frameworks */, 46383DC6A22A87056E5B40EC /* Pods */, A33E60A21DE761C90065CBD8 /* Products */, AF1E1B521E66822C00ECE039 /* Tests */, 2D1F7FE31E49DD90004D944B /* TvOSExamples */, ); indentWidth = 2; sourceTree = ""; tabWidth = 2; }; A33E60A21DE761C90065CBD8 /* Products */ = { isa = PBXGroup; children = ( A33E60A11DE761C90065CBD8 /* HeroExamples.app */, A306D3B21E1C7A2E00B6C23A /* Hero.framework */, 2D1F7FBF1E49DCB5004D944B /* Hero.framework */, 2D1F7FE21E49DD90004D944B /* HeroTvOSExamples.app */, AF1E1B511E66822C00ECE039 /* HeroTests.xctest */, ); name = Products; sourceTree = ""; }; A33E60A31DE761C90065CBD8 /* LegacyExamples */ = { isa = PBXGroup; children = ( A33E60B71DE7621C0065CBD8 /* Examples */, A35949171E1A2BE60095F407 /* LegacyExampleViewController.swift */, A33E60A81DE761C90065CBD8 /* Main.storyboard */, B1275D961E4C0D850099A0E9 /* PluginViewController.swift */, ); path = LegacyExamples; sourceTree = ""; }; A33E60B71DE7621C0065CBD8 /* Examples */ = { isa = PBXGroup; children = ( B114B6931E412A1B0009CEDE /* AppleHomePage */, A32D2D111E4E9899008D35FF /* BuiltInTransition */, A33E60B81DE7621C0065CBD8 /* CityGuide */, A3499D9D1DF202350049B541 /* ImageGallery */, B185A4E91DFA6FE700C3B85D /* ListToGrid */, A32D2D0E1E4D5463008D35FF /* Menu */, B19F76AE1E46C449002DBC58 /* VideoPlayer */, B147F2621FAEA8F0006475A3 /* Navigation */, B19F769A1E46C3A2002DBC58 /* Basic.storyboard */, B19F769C1E46C3A2002DBC58 /* MusicPlayer.storyboard */, ); path = Examples; sourceTree = ""; }; A33E60B81DE7621C0065CBD8 /* CityGuide */ = { isa = PBXGroup; children = ( A33E60B91DE7621C0065CBD8 /* City.swift */, B19F76A01E46C3C2002DBC58 /* CityGuide.storyboard */, A33E60BA1DE7621C0065CBD8 /* CityGuideCell.swift */, A33E60BB1DE7621C0065CBD8 /* CityGuideViewController.swift */, A33E60BC1DE7621C0065CBD8 /* CityViewController.swift */, ); path = CityGuide; sourceTree = ""; }; A33E60C21DE76CEF0065CBD8 /* Resources */ = { isa = PBXGroup; children = ( A33E60A41DE761C90065CBD8 /* AppDelegate.swift */, A33E60AB1DE761C90065CBD8 /* Assets.xcassets */, A33E60B01DE761C90065CBD8 /* Info.plist */, A33E60AD1DE761C90065CBD8 /* LaunchScreen.storyboard */, A33E60B61DE7621C0065CBD8 /* UIKit+HeroExamples.swift */, ); path = Resources; sourceTree = ""; }; A3499D9D1DF202350049B541 /* ImageGallery */ = { isa = PBXGroup; children = ( A304BF891DF647FC00A03345 /* ImageCells.swift */, B19F76A41E46C3D7002DBC58 /* ImageGallery.storyboard */, A3499D9E1DF2024E0049B541 /* ImageGalleryCollectionViewController.swift */, A313499A1E1E2AED00EB5139 /* ImageLibrary.swift */, A304BF831DF2717900A03345 /* ImageViewController.swift */, B19F76A51E46C3D7002DBC58 /* ImageViewer.storyboard */, ); path = ImageGallery; sourceTree = ""; }; A3B8C5682083376C00E112F6 /* Examples */ = { isa = PBXGroup; children = ( A3B8C5662083376100E112F6 /* MainViewController.swift */, A3D060C120833B4E00E48927 /* ExampleBaseViewController.swift */, A3D060BF20833B0700E48927 /* BuiltInTransitionExample.swift */, A3D060C320833D0400E48927 /* MatchExample.swift */, 62EFDDAB236F4FC200F3E85E /* SwiftUIMatchExample.swift */, A3D060C5208348CB00E48927 /* MatchInCollectionExample.swift */, A3D060C720834FF100E48927 /* AppStoreCardExample.swift */, A33E60C21DE76CEF0065CBD8 /* Resources */, ); path = Examples; sourceTree = ""; }; AF1E1B521E66822C00ECE039 /* Tests */ = { isa = PBXGroup; children = ( AF1E1B531E66822C00ECE039 /* HeroTests.swift */, AF1E1B551E66822C00ECE039 /* Info.plist */, ); path = Tests; sourceTree = ""; }; AFA306D21E6B447200CAF719 /* Parser */ = { isa = PBXGroup; children = ( AF6D93491E65168D00FCD55E /* HeroStringConvertible.swift */, AFA306C61E6B446C00CAF719 /* Lexer.swift */, AFA306C71E6B446C00CAF719 /* Nodes.swift */, AFA306C81E6B446C00CAF719 /* Parser.swift */, AFA306C91E6B446C00CAF719 /* Regex.swift */, ); path = Parser; sourceTree = ""; }; B114B6931E412A1B0009CEDE /* AppleHomePage */ = { isa = PBXGroup; children = ( B19F76981E46C38E002DBC58 /* AppleHomePage.storyboard */, B114B68F1E412A0B0009CEDE /* AppleProductViewController.swift */, ); path = AppleHomePage; sourceTree = ""; }; B11769D81EF8626C00A1373A /* Transition */ = { isa = PBXGroup; children = ( B16B75331EF461090018DBEF /* HeroProgressRunner.swift */, B1D816E41EF5A6AE007B9776 /* HeroTransition+Start.swift */, B1D816EA1EF5A720007B9776 /* HeroTransition+Animate.swift */, B1D816E71EF5A6FE007B9776 /* HeroTransition+Complete.swift */, B1D816E11EF5A630007B9776 /* HeroTransition+CustomTransition.swift */, B16197DF1EF451C400A540D2 /* HeroTransition+Interactive.swift */, B17D88881EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift */, B17D88851EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift */, B17D888B1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift */, A37D7B511E2C0CBD00AC1959 /* HeroTransition.swift */, B16B75301EF45A110018DBEF /* HeroTransitionState.swift */, ); path = Transition; sourceTree = ""; }; B147F2621FAEA8F0006475A3 /* Navigation */ = { isa = PBXGroup; children = ( B147F2631FAEA8F0006475A3 /* FirstViewController.swift */, B147F2641FAEA8F0006475A3 /* Navigation.storyboard */, ); path = Navigation; sourceTree = ""; }; B185A4E91DFA6FE700C3B85D /* ListToGrid */ = { isa = PBXGroup; children = ( B185A4E71DFA6FE200C3B85D /* GridCollectionViewController.swift */, B185A4E51DFA6E0C00C3B85D /* ListTableViewController.swift */, B19F76A21E46C3CB002DBC58 /* ListToGrid.storyboard */, ); path = ListToGrid; sourceTree = ""; }; B19F76AE1E46C449002DBC58 /* VideoPlayer */ = { isa = PBXGroup; children = ( B19F76AF1E46C449002DBC58 /* VideoPlayer.storyboard */, B19F76B01E46C449002DBC58 /* VideoPlayerViewController.swift */, ); path = VideoPlayer; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 2D1F7FBC1E49DCB5004D944B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 2D1F7FDC1E49DD3C004D944B /* Hero.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; A306D3AF1E1C7A2E00B6C23A /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( A306D3B61E1C7A2E00B6C23A /* Hero.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 2D1F7FBE1E49DCB5004D944B /* Hero (tvOS) */ = { isa = PBXNativeTarget; buildConfigurationList = 2D1F7FC61E49DCB5004D944B /* Build configuration list for PBXNativeTarget "Hero (tvOS)" */; buildPhases = ( 2D1F7FBA1E49DCB5004D944B /* Sources */, 2D1F7FBB1E49DCB5004D944B /* Frameworks */, 2D1F7FBC1E49DCB5004D944B /* Headers */, 2D1F7FBD1E49DCB5004D944B /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "Hero (tvOS)"; productName = "Hero (tvOS)"; productReference = 2D1F7FBF1E49DCB5004D944B /* Hero.framework */; productType = "com.apple.product-type.framework"; }; 2D1F7FE11E49DD90004D944B /* HeroTvOSExamples */ = { isa = PBXNativeTarget; buildConfigurationList = 2D1F7FEE1E49DD90004D944B /* Build configuration list for PBXNativeTarget "HeroTvOSExamples" */; buildPhases = ( 89DC76B30A0BF7FD724C24D3 /* [CP] Check Pods Manifest.lock */, 2D1F7FDE1E49DD90004D944B /* Sources */, 2D1F7FDF1E49DD90004D944B /* Frameworks */, 2D1F7FE01E49DD90004D944B /* Resources */, ); buildRules = ( ); dependencies = ( 2D1F7FF41E49E05A004D944B /* PBXTargetDependency */, ); name = HeroTvOSExamples; productName = HeroTvOSExamples; productReference = 2D1F7FE21E49DD90004D944B /* HeroTvOSExamples.app */; productType = "com.apple.product-type.application"; }; A306D3B11E1C7A2E00B6C23A /* Hero (iOS) */ = { isa = PBXNativeTarget; buildConfigurationList = A306D3BE1E1C7A2E00B6C23A /* Build configuration list for PBXNativeTarget "Hero (iOS)" */; buildPhases = ( A306D3AD1E1C7A2E00B6C23A /* Sources */, A306D3AE1E1C7A2E00B6C23A /* Frameworks */, A306D3AF1E1C7A2E00B6C23A /* Headers */, A306D3B01E1C7A2E00B6C23A /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "Hero (iOS)"; productName = Hero; productReference = A306D3B21E1C7A2E00B6C23A /* Hero.framework */; productType = "com.apple.product-type.framework"; }; A33E60A01DE761C90065CBD8 /* HeroExamples */ = { isa = PBXNativeTarget; buildConfigurationList = A33E60B31DE761C90065CBD8 /* Build configuration list for PBXNativeTarget "HeroExamples" */; buildPhases = ( AB630E15554685FDB346A796 /* [CP] Check Pods Manifest.lock */, A0BDF7221E2FCC5A0028778F /* Swiftlint */, A33E609D1DE761C90065CBD8 /* Sources */, A33E609E1DE761C90065CBD8 /* Frameworks */, A33E609F1DE761C90065CBD8 /* Resources */, 23B031AF37B3297143AE7376 /* [CP] Embed Pods Frameworks */, A306D3BA1E1C7A2E00B6C23A /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( A306D3B81E1C7A2E00B6C23A /* PBXTargetDependency */, ); name = HeroExamples; productName = HeroExamples; productReference = A33E60A11DE761C90065CBD8 /* HeroExamples.app */; productType = "com.apple.product-type.application"; }; AF1E1B501E66822C00ECE039 /* HeroTests */ = { isa = PBXNativeTarget; buildConfigurationList = AF1E1B581E66822C00ECE039 /* Build configuration list for PBXNativeTarget "HeroTests" */; buildPhases = ( 3673D17D1C42FCAD03311A99 /* [CP] Check Pods Manifest.lock */, AF1E1B4D1E66822C00ECE039 /* Sources */, AF1E1B4E1E66822C00ECE039 /* Frameworks */, AF1E1B4F1E66822C00ECE039 /* Resources */, ); buildRules = ( ); dependencies = ( AF1E1B571E66822C00ECE039 /* PBXTargetDependency */, ); name = HeroTests; productName = HeroTests; productReference = AF1E1B511E66822C00ECE039 /* HeroTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ A33E60991DE761C90065CBD8 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0820; LastUpgradeCheck = 1240; ORGANIZATIONNAME = "Hero Transitions"; TargetAttributes = { 2D1F7FBE1E49DCB5004D944B = { CreatedOnToolsVersion = 8.2; LastSwiftMigration = 1240; ProvisioningStyle = Automatic; }; 2D1F7FE11E49DD90004D944B = { CreatedOnToolsVersion = 8.2; LastSwiftMigration = 1240; ProvisioningStyle = Automatic; }; A306D3B11E1C7A2E00B6C23A = { CreatedOnToolsVersion = 8.2.1; LastSwiftMigration = 1120; ProvisioningStyle = Automatic; }; A33E60A01DE761C90065CBD8 = { CreatedOnToolsVersion = 8.0; LastSwiftMigration = 1120; ProvisioningStyle = Automatic; }; AF1E1B501E66822C00ECE039 = { CreatedOnToolsVersion = 8.2; LastSwiftMigration = 1120; ProvisioningStyle = Automatic; TestTargetID = A33E60A01DE761C90065CBD8; }; }; }; buildConfigurationList = A33E609C1DE761C90065CBD8 /* Build configuration list for PBXProject "Hero" */; compatibilityVersion = "Xcode 11.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = A33E60981DE761C90065CBD8; productRefGroup = A33E60A21DE761C90065CBD8 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( A306D3B11E1C7A2E00B6C23A /* Hero (iOS) */, 2D1F7FBE1E49DCB5004D944B /* Hero (tvOS) */, A33E60A01DE761C90065CBD8 /* HeroExamples */, 2D1F7FE11E49DD90004D944B /* HeroTvOSExamples */, AF1E1B501E66822C00ECE039 /* HeroTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 2D1F7FBD1E49DCB5004D944B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 2D1F7FE01E49DD90004D944B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( A32D2CF21E4A7DC3008D35FF /* Assets.xcassets in Resources */, A32D2D051E4A81D5008D35FF /* ImageViewer.storyboard in Resources */, A32D2D031E4A8153008D35FF /* ImageGallery.storyboard in Resources */, A32D2D021E4A8153008D35FF /* Basic.storyboard in Resources */, 2D1F7FEA1E49DD90004D944B /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; A306D3B01E1C7A2E00B6C23A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; A33E609F1DE761C90065CBD8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( A33E60AF1DE761C90065CBD8 /* LaunchScreen.storyboard in Resources */, A33E60AC1DE761C90065CBD8 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; AF1E1B4F1E66822C00ECE039 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 23B031AF37B3297143AE7376 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-HeroExamples/Pods-HeroExamples-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-HeroExamples/Pods-HeroExamples-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-HeroExamples/Pods-HeroExamples-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 3673D17D1C42FCAD03311A99 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-HeroTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 89DC76B30A0BF7FD724C24D3 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-HeroTvOSExamples-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; A0BDF7221E2FCC5A0028778F /* Swiftlint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = Swiftlint; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; }; AB630E15554685FDB346A796 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-HeroExamples-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 2D1F7FBA1E49DCB5004D944B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( B1193AB71E525CD8005B1C87 /* HeroViewPropertyViewContext.swift in Sources */, 2D1F7FD01E49DD13004D944B /* MatchPreprocessor.swift in Sources */, 2D1F7FD61E49DD18004D944B /* DispatchQueue+Hero.swift in Sources */, 2D1F7FCB1E49DD08004D944B /* HeroTargetState.swift in Sources */, B17D888D1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift in Sources */, B35264CF2454FEF300D33861 /* Locale+Hero.swift in Sources */, B1D816E01EF5A5DF007B9776 /* HeroViewControllerDelegate.swift in Sources */, B1193ABA1E525D12005B1C87 /* HeroAnimatorViewContext.swift in Sources */, 2D1F7FCA1E49DD08004D944B /* HeroPlugin.swift in Sources */, 2D1F7FDA1E49DD21004D944B /* HeroDebugPlugin.swift in Sources */, B17D888A1EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift in Sources */, 4D307DF520E3C6DC00DD9F65 /* HeroModifier+Advanced.swift in Sources */, 2D1F7FDB1E49DD21004D944B /* HeroDebugView.swift in Sources */, B1D834051F02E7C0009E1E36 /* ConditionalPreprocessor.swift in Sources */, B16197E11EF451C500A540D2 /* HeroTransition+Interactive.swift in Sources */, 2D1F7FC91E49DD08004D944B /* HeroModifier.swift in Sources */, B16B75351EF461090018DBEF /* HeroProgressRunner.swift in Sources */, 2D1F7FD71E49DD18004D944B /* UIKit+Hero.swift in Sources */, B1D816E91EF5A6FE007B9776 /* HeroTransition+Complete.swift in Sources */, AF6D934B1E65168D00FCD55E /* HeroStringConvertible.swift in Sources */, 2D1F7FD81E49DD1D004D944B /* HeroDefaultAnimator.swift in Sources */, 2D1F7FCC1E49DD08004D944B /* HeroTypes.swift in Sources */, B101B2CC1E56140B007E7112 /* UIView+Hero.swift in Sources */, A32D2D141E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift in Sources */, B101B2CF1E561421007E7112 /* UIViewController+Hero.swift in Sources */, 2D1F7FCD1E49DD13004D944B /* BasePreprocessor.swift in Sources */, 2D1F7FD41E49DD18004D944B /* CAMediaTimingFunction+Hero.swift in Sources */, B16B75321EF45A110018DBEF /* HeroTransitionState.swift in Sources */, 2D1F7FD21E49DD18004D944B /* Array+HeroModifier.swift in Sources */, 2D1F7FD51E49DD18004D944B /* CG+Hero.swift in Sources */, 2D1F7FD91E49DD1D004D944B /* HeroCoreAnimationViewContext.swift in Sources */, AFA306D11E6B446C00CAF719 /* Regex.swift in Sources */, B1D816E31EF5A630007B9776 /* HeroTransition+CustomTransition.swift in Sources */, AFA306CF1E6B446C00CAF719 /* Parser.swift in Sources */, 1F0287FB2173F3C80008FA3B /* SwiftSupport.swift in Sources */, 2D1F7FD31E49DD18004D944B /* CALayer+Hero.swift in Sources */, 2D1F7FC71E49DD02004D944B /* HeroTransition.swift in Sources */, 2D1F7FC81E49DD04004D944B /* HeroContext.swift in Sources */, B16ECD041E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift in Sources */, 5C5442AA2004092500E1E326 /* HeroCompatible.swift in Sources */, B1D816E61EF5A6AE007B9776 /* HeroTransition+Start.swift in Sources */, AFA306CB1E6B446C00CAF719 /* Lexer.swift in Sources */, B1D816EC1EF5A720007B9776 /* HeroTransition+Animate.swift in Sources */, 2D1F7FD11E49DD13004D944B /* SourcePreprocessor.swift in Sources */, B17D88871EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift in Sources */, 2D1F7FCF1E49DD13004D944B /* IgnoreSubviewModifiersPreprocessor.swift in Sources */, 2D1F7FCE1E49DD13004D944B /* CascadePreprocessor.swift in Sources */, AFA306CD1E6B446C00CAF719 /* Nodes.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 2D1F7FDE1E49DD90004D944B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F482F0C0235D7A3A002E97ED /* ImageGalleryCollectionViewController.swift in Sources */, A32D2CFC1E4A80DC008D35FF /* UIKit+HeroExamples.swift in Sources */, 2D1F7FE71E49DD90004D944B /* TVImageGalleryViewController.swift in Sources */, F482F0BF235D7808002E97ED /* UIColor+HexString.swift in Sources */, F482F0C1235D7A51002E97ED /* ImageViewController.swift in Sources */, F482F0C3235D7A65002E97ED /* ImageLibrary.swift in Sources */, F482F0C2235D7A5B002E97ED /* ImageCells.swift in Sources */, 2D1F7FE51E49DD90004D944B /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; A306D3AD1E1C7A2E00B6C23A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( B1193AB61E525CD8005B1C87 /* HeroViewPropertyViewContext.swift in Sources */, A37D7B4B1E2C0C9300AC1959 /* Array+HeroModifier.swift in Sources */, A37D7B4D1E2C0C9300AC1959 /* CAMediaTimingFunction+Hero.swift in Sources */, A37D7B5D1E2C0CBD00AC1959 /* HeroModifier.swift in Sources */, B17D888C1EF5A5500048D3E8 /* HeroTransition+UIViewControllerTransitioningDelegate.swift in Sources */, B35264CE2454FEF300D33861 /* Locale+Hero.swift in Sources */, B1D816DF1EF5A5DF007B9776 /* HeroViewControllerDelegate.swift in Sources */, B1193AB91E525D12005B1C87 /* HeroAnimatorViewContext.swift in Sources */, A37D7B5B1E2C0CBD00AC1959 /* HeroDefaultAnimator.swift in Sources */, A37D7B5A1E2C0CBD00AC1959 /* HeroContext.swift in Sources */, B17D88891EF5A5330048D3E8 /* HeroTransition+UINavigationControllerDelegate.swift in Sources */, 4D307DF420E3C6DC00DD9F65 /* HeroModifier+Advanced.swift in Sources */, A37D7B5C1E2C0CBD00AC1959 /* HeroCoreAnimationViewContext.swift in Sources */, B1D834041F02E7C0009E1E36 /* ConditionalPreprocessor.swift in Sources */, B16197E01EF451C500A540D2 /* HeroTransition+Interactive.swift in Sources */, A37D7B641E2C0CD100AC1959 /* HeroDebugView.swift in Sources */, B16B75341EF461090018DBEF /* HeroProgressRunner.swift in Sources */, A37D7B601E2C0CBD00AC1959 /* HeroTypes.swift in Sources */, B1D816E81EF5A6FE007B9776 /* HeroTransition+Complete.swift in Sources */, AF6D934A1E65168D00FCD55E /* HeroStringConvertible.swift in Sources */, A37D7B441E2C0C7E00AC1959 /* SourcePreprocessor.swift in Sources */, A37D7B5E1E2C0CBD00AC1959 /* HeroPlugin.swift in Sources */, B101B2CB1E56140A007E7112 /* UIView+Hero.swift in Sources */, A32D2D131E501C4F008D35FF /* HeroModifier+HeroStringConvertible.swift in Sources */, B101B2CE1E561421007E7112 /* UIViewController+Hero.swift in Sources */, A37D7B421E2C0C7E00AC1959 /* IgnoreSubviewModifiersPreprocessor.swift in Sources */, A3298CDA1E304851005B06BB /* BasePreprocessor.swift in Sources */, B16B75311EF45A110018DBEF /* HeroTransitionState.swift in Sources */, A37D7B4E1E2C0C9300AC1959 /* CG+Hero.swift in Sources */, A37D7B4F1E2C0C9300AC1959 /* DispatchQueue+Hero.swift in Sources */, A37D7B591E2C0CBD00AC1959 /* HeroTransition.swift in Sources */, AFA306D01E6B446C00CAF719 /* Regex.swift in Sources */, B1D816E21EF5A630007B9776 /* HeroTransition+CustomTransition.swift in Sources */, AFA306CE1E6B446C00CAF719 /* Parser.swift in Sources */, 1F0287FA2173F3C80008FA3B /* SwiftSupport.swift in Sources */, A37D7B4C1E2C0C9300AC1959 /* CALayer+Hero.swift in Sources */, A37D7B431E2C0C7E00AC1959 /* MatchPreprocessor.swift in Sources */, A37D7B5F1E2C0CBD00AC1959 /* HeroTargetState.swift in Sources */, B16ECD031E4FC0B300EAE0E0 /* DefaultAnimationPreprocessor.swift in Sources */, 5C6972902002CDBD001A5051 /* HeroCompatible.swift in Sources */, B1D816E51EF5A6AE007B9776 /* HeroTransition+Start.swift in Sources */, AFA306CA1E6B446C00CAF719 /* Lexer.swift in Sources */, B1D816EB1EF5A720007B9776 /* HeroTransition+Animate.swift in Sources */, A37D7B411E2C0C7E00AC1959 /* CascadePreprocessor.swift in Sources */, B17D88861EF5A51C0048D3E8 /* HeroTransition+UITabBarControllerDelegate.swift in Sources */, A37D7B501E2C0C9300AC1959 /* UIKit+Hero.swift in Sources */, A37D7B631E2C0CD100AC1959 /* HeroDebugPlugin.swift in Sources */, AFA306CC1E6B446C00CAF719 /* Nodes.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; A33E609D1DE761C90065CBD8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F482F0BE235D7808002E97ED /* UIColor+HexString.swift in Sources */, A33E60BD1DE7621C0065CBD8 /* UIKit+HeroExamples.swift in Sources */, 62EFDDAC236F4FC200F3E85E /* SwiftUIMatchExample.swift in Sources */, A3D060C820834FF100E48927 /* AppStoreCardExample.swift in Sources */, A3D060C420833D0400E48927 /* MatchExample.swift in Sources */, A3D060C020833B0800E48927 /* BuiltInTransitionExample.swift in Sources */, A33E60A51DE761C90065CBD8 /* AppDelegate.swift in Sources */, A3D060C6208348CB00E48927 /* MatchInCollectionExample.swift in Sources */, A3D060C220833B4E00E48927 /* ExampleBaseViewController.swift in Sources */, A3B8C5672083376100E112F6 /* MainViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AF1E1B4D1E66822C00ECE039 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AF1E1B541E66822C00ECE039 /* HeroTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 2D1F7FF41E49E05A004D944B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 2D1F7FBE1E49DCB5004D944B /* Hero (tvOS) */; targetProxy = 2D1F7FF31E49E05A004D944B /* PBXContainerItemProxy */; }; A306D3B81E1C7A2E00B6C23A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = A306D3B11E1C7A2E00B6C23A /* Hero (iOS) */; targetProxy = A306D3B71E1C7A2E00B6C23A /* PBXContainerItemProxy */; }; AF1E1B571E66822C00ECE039 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = A33E60A01DE761C90065CBD8 /* HeroExamples */; targetProxy = AF1E1B561E66822C00ECE039 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 2D1F7FE81E49DD90004D944B /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 2D1F7FE91E49DD90004D944B /* Base */, ); name = Main.storyboard; path = .; sourceTree = ""; }; A33E60A81DE761C90065CBD8 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( A33E60A91DE761C90065CBD8 /* Base */, F482F0C5235D7C4C002E97ED /* en */, ); name = Main.storyboard; path = .; sourceTree = ""; }; A33E60AD1DE761C90065CBD8 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( A33E60AE1DE761C90065CBD8 /* Base */, ); name = LaunchScreen.storyboard; path = .; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 2D1F7FC41E49DCB5004D944B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.Hero; PRODUCT_NAME = Hero; SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 2D1F7FC51E49DCB5004D944B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_IDENTITY = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.Hero; PRODUCT_NAME = Hero; SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 2D1F7FEF1E49DD90004D944B /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 86C87C73D89E75C8443B5071 /* Pods-HeroTvOSExamples.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = TvOSExamples/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.HeroTvOSExamples; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.0; }; name = Debug; }; 2D1F7FF01E49DD90004D944B /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = A41D45F75C2C4244CC105281 /* Pods-HeroTvOSExamples.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = TvOSExamples/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.HeroTvOSExamples; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 10.0; }; name = Release; }; A306D3BC1E1C7A2E00B6C23A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.Hero; PRODUCT_NAME = Hero; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; A306D3BD1E1C7A2E00B6C23A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.Hero; PRODUCT_NAME = Hero; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; A33E60B11DE761C90065CBD8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.0; MARKETING_VERSION = 1.6.4; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; SWIFT_VERSION = 5.0; }; name = Debug; }; A33E60B21DE761C90065CBD8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.0; MARKETING_VERSION = 1.6.4; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; SWIFT_VERSION = 5.0; VALIDATE_PRODUCT = YES; }; name = Release; }; A33E60B41DE761C90065CBD8 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5CD4F09A588E81DA75C2BE38 /* Pods-HeroExamples.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/Examples/Resources/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); OTHER_LDFLAGS = ( "$(inherited)", "-framework", "\"CollectionKit\"", "-framework", "\"Foundation\"", "-framework", "\"UIKit\"", "-weak_framework", SwiftUI, "-weak_framework", Combine, ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.HeroExamples; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; A33E60B51DE761C90065CBD8 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = C377744CBFF1E24426E80F55 /* Pods-HeroExamples.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/Examples/Resources/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); OTHER_LDFLAGS = ( "$(inherited)", "-framework", "\"CollectionKit\"", "-framework", "\"Foundation\"", "-framework", "\"UIKit\"", "-weak_framework", SwiftUI, "-weak_framework", Combine, ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.HeroExamples; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; AF1E1B591E66822C00ECE039 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = C51A6465EC2CB38D82F28B93 /* Pods-HeroTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = Tests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); OTHER_LDFLAGS = ( "$(inherited)", "-framework", "\"CollectionKit\"", "-framework", "\"Foundation\"", "-framework", "\"UIKit\"", "-weak_framework", Combine, "-weak_framework", SwiftUI, ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.HeroTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HeroExamples.app/HeroExamples"; }; name = Debug; }; AF1E1B5A1E66822C00ECE039 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5CEC69C9A9A60129002FD931 /* Pods-HeroTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = Tests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); OTHER_LDFLAGS = ( "$(inherited)", "-framework", "\"CollectionKit\"", "-framework", "\"Foundation\"", "-framework", "\"UIKit\"", "-weak_framework", Combine, "-weak_framework", SwiftUI, ); PRODUCT_BUNDLE_IDENTIFIER = com.lkzhao.HeroTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HeroExamples.app/HeroExamples"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 2D1F7FC61E49DCB5004D944B /* Build configuration list for PBXNativeTarget "Hero (tvOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( 2D1F7FC41E49DCB5004D944B /* Debug */, 2D1F7FC51E49DCB5004D944B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 2D1F7FEE1E49DD90004D944B /* Build configuration list for PBXNativeTarget "HeroTvOSExamples" */ = { isa = XCConfigurationList; buildConfigurations = ( 2D1F7FEF1E49DD90004D944B /* Debug */, 2D1F7FF01E49DD90004D944B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; A306D3BE1E1C7A2E00B6C23A /* Build configuration list for PBXNativeTarget "Hero (iOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( A306D3BC1E1C7A2E00B6C23A /* Debug */, A306D3BD1E1C7A2E00B6C23A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; A33E609C1DE761C90065CBD8 /* Build configuration list for PBXProject "Hero" */ = { isa = XCConfigurationList; buildConfigurations = ( A33E60B11DE761C90065CBD8 /* Debug */, A33E60B21DE761C90065CBD8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; A33E60B31DE761C90065CBD8 /* Build configuration list for PBXNativeTarget "HeroExamples" */ = { isa = XCConfigurationList; buildConfigurations = ( A33E60B41DE761C90065CBD8 /* Debug */, A33E60B51DE761C90065CBD8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AF1E1B581E66822C00ECE039 /* Build configuration list for PBXNativeTarget "HeroTests" */ = { isa = XCConfigurationList; buildConfigurations = ( AF1E1B591E66822C00ECE039 /* Debug */, AF1E1B5A1E66822C00ECE039 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = A33E60991DE761C90065CBD8 /* Project object */; } ================================================ FILE: Hero.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Hero.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: Hero.xcodeproj/xcshareddata/xcschemes/Hero (tvOS).xcscheme ================================================ ================================================ FILE: Hero.xcodeproj/xcshareddata/xcschemes/Hero.xcscheme ================================================ ================================================ FILE: Hero.xcodeproj/xcshareddata/xcschemes/HeroExamples.xcscheme ================================================ ================================================ FILE: Hero.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Hero.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: Hero.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ BuildSystemType Latest PreviewsEnabled ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Luke Zhao Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LegacyExamples/Base.lproj/Main.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/AppleHomePage/AppleHomePage.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/AppleHomePage/AppleProductViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero let viewControllerIDs = ["iphone", "watch", "macbook"] class AppleProductViewController: UIViewController, HeroViewControllerDelegate { var panGR: UIPanGestureRecognizer! @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var primaryLabel: UILabel! @IBOutlet weak var secondaryLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() panGR = UIPanGestureRecognizer(target: self, action: #selector(pan)) view.addGestureRecognizer(panGR) } func applyShrinkModifiers() { view.hero.modifiers = nil primaryLabel.hero.modifiers = [.translate(x:-50, y:(view.center.y - primaryLabel.center.y)/10), .scale(0.9), HeroModifier.duration(0.3)] secondaryLabel.hero.modifiers = [.translate(x:-50, y:(view.center.y - secondaryLabel.center.y)/10), .scale(0.9), HeroModifier.duration(0.3)] imageView.hero.modifiers = [.translate(x:-80), .scale(0.9), HeroModifier.duration(0.3)] } func applySlideModifiers() { view.hero.modifiers = [.translate(x: view.bounds.width), .duration(0.3), .beginWith(modifiers: [.zPosition(2)])] primaryLabel.hero.modifiers = [.translate(x:100), .duration(0.3)] secondaryLabel.hero.modifiers = [.translate(x:100), .duration(0.3)] imageView.hero.modifiers = nil } enum TransitionState { case normal, slidingLeft, slidingRight } var state: TransitionState = .normal weak var nextVC: AppleProductViewController? @objc func pan() { let translateX = panGR.translation(in: nil).x let velocityX = panGR.velocity(in: nil).x switch panGR.state { case .began, .changed: let nextState: TransitionState if state == .normal { nextState = velocityX < 0 ? .slidingLeft : .slidingRight } else { nextState = translateX < 0 ? .slidingLeft : .slidingRight } if nextState != state { Hero.shared.cancel(animate: false) let currentIndex = viewControllerIDs.index(of: self.title!)! let nextIndex = (currentIndex + (nextState == .slidingLeft ? 1 : viewControllerIDs.count - 1)) % viewControllerIDs.count nextVC = self.storyboard!.instantiateViewController(withIdentifier: viewControllerIDs[nextIndex]) as? AppleProductViewController if nextState == .slidingLeft { applyShrinkModifiers() nextVC!.applySlideModifiers() } else { applySlideModifiers() nextVC!.applyShrinkModifiers() } state = nextState hero.replaceViewController(with: nextVC!) } else { let progress = abs(translateX / view.bounds.width) Hero.shared.update(progress) if state == .slidingLeft, let nextVC = nextVC { Hero.shared.apply(modifiers: [.translate(x: view.bounds.width + translateX)], to: nextVC.view) } else { Hero.shared.apply(modifiers: [.translate(x: translateX)], to: view) } } default: let progress = (translateX + velocityX) / view.bounds.width if (progress < 0) == (state == .slidingLeft) && abs(progress) > 0.3 { Hero.shared.finish() } else { Hero.shared.cancel() } state = .normal } } func heroWillStartAnimatingTo(viewController: UIViewController) { if !(viewController is AppleProductViewController) { view.hero.modifiers = [.ignoreSubviewModifiers(recursive: true)] } } } ================================================ FILE: LegacyExamples/Examples/Basic.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/BuiltInTransition/AnimationSelectTableViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero import ChameleonFramework class AnimationSelectHeaderCell: UITableViewCell { @IBOutlet weak var backButton: UIButton! @IBOutlet weak var heroLogo: TemplateImageView! @IBOutlet weak var promptLabel: UILabel! } class AnimationSelectTableViewController: UITableViewController { var animations: [HeroDefaultAnimationType] = [ .push(direction: .left), .pull(direction: .left), .slide(direction: .left), .zoomSlide(direction: .left), .cover(direction: .up), .uncover(direction: .up), .pageIn(direction: .left), .pageOut(direction: .left), .fade, .zoom, .zoomOut, .none ] var labelColor: UIColor! override func viewDidLoad() { super.viewDidLoad() tableView.backgroundColor = UIColor.randomFlat labelColor = UIColor(contrastingBlackOrWhiteColorOn: tableView.backgroundColor!, isFlat: true) let screenEdgePanGR = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handlePan(gr:))) screenEdgePanGR.edges = .left view.addGestureRecognizer(screenEdgePanGR) } @objc func handlePan(gr: UIPanGestureRecognizer) { switch gr.state { case .began: dismiss(animated: true, completion: nil) case .changed: let progress = gr.translation(in: nil).x / view.bounds.width Hero.shared.update(progress) default: if (gr.translation(in: nil).x + gr.velocity(in: nil).x) / view.bounds.width > 0.5 { Hero.shared.finish() } else { Hero.shared.cancel() } } } override func numberOfSections(in tableView: UITableView) -> Int { return 2 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return section == 0 ? 1 : animations.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if indexPath.section == 0 { let header = tableView.dequeueReusableCell(withIdentifier: "header", for: indexPath) as! AnimationSelectHeaderCell header.heroLogo.tintColor = labelColor header.promptLabel.textColor = labelColor header.backButton.tintColor = labelColor return header } let cell = tableView.dequeueReusableCell(withIdentifier: "item", for: indexPath) cell.textLabel!.text = animations[indexPath.item].label cell.textLabel!.textColor = labelColor return cell } override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath.section == 0 ? nil : indexPath } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let vc = self.storyboard!.instantiateViewController(withIdentifier: "animationSelect") vc.hero.modalAnimationType = animations[indexPath.item] hero.replaceViewController(with: vc) } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return indexPath.section == 0 ? 300 : 44 } } ================================================ FILE: LegacyExamples/Examples/BuiltInTransition/BuiltInTransitions.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/CityGuide/City.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit struct City { var name: String var image: UIImage var shortDescription: String var description: String static var cities = [ City(name: "Vancouver", image: #imageLiteral(resourceName: "vancouver"), shortDescription: "City in British Columbia", description: "Vancouver, a bustling west coast seaport in British Columbia, is among Canada’s densest, most ethnically diverse cities. A popular filming location, it’s surrounded by mountains, and also has thriving art, theatre and music scenes. Vancouver Art Gallery is known for its works by regional artists, while the Museum of Anthropology houses preeminent First Nations collections."), City(name: "Toronto", image: #imageLiteral(resourceName: "toronto"), shortDescription: "City in Ontario", description: "Toronto, the capital of the province of Ontario, is a major Canadian city along Lake Ontario’s northwestern shore. It's a dynamic metropolis with a core of soaring skyscrapers, all dwarfed by the iconic CN Tower. Toronto also has many green spaces, from the orderly oval of Queen’s Park to 400-acre High Park and its trails, sports facilities and zoo."), City(name: "Montreal", image: #imageLiteral(resourceName: "montreal"), shortDescription: "City in Québec", description: "Montréal is the largest city in Canada's Québec province. It’s set on an island in the Saint Lawrence River and named after Mt. Royal, the triple-peaked hill at its heart. Its boroughs, many of which were once independent cities, include neighbourhoods ranging from cobblestoned, French colonial Vieux-Montréal – with the Gothic Revival Notre-Dame Basilica at its centre – to bohemian Plateau.") ] } ================================================ FILE: LegacyExamples/Examples/CityGuide/CityGuide.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/CityGuide/CityGuideCell.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit class CityCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var descriptionLabel: UILabel! var useShortDescription: Bool = true var city: City? { didSet { guard let city = city else { return } let name = city.name hero.id = "\(name)" nameLabel.text = name imageView.image = city.image descriptionLabel.text = useShortDescription ? city.shortDescription : city.description } } } ================================================ FILE: LegacyExamples/Examples/CityGuide/CityGuideViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit class CityGuideViewController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! var cities = City.cities override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let currentCell = sender as? CityCell, let vc = segue.destination as? CityViewController, let currentCellIndex = collectionView.indexPath(for: currentCell) { vc.selectedIndex = currentCellIndex } } } extension CityGuideViewController:UICollectionViewDataSource, UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return cities.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as? CityCell)! cell.city = cities[indexPath.item] return cell } } ================================================ FILE: LegacyExamples/Examples/CityGuide/CityViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit class CityViewController: UIViewController { var selectedIndex: IndexPath! var cities: [City] = City.cities @IBOutlet weak var collectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() view.layoutIfNeeded() collectionView.reloadData() collectionView.scrollToItem(at: selectedIndex, at: .centeredHorizontally, animated: false) } } extension CityViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return cities.count } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return view.frame.size } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as? CityCell)! cell.useShortDescription = false cell.city = cities[indexPath.item] return cell } } ================================================ FILE: LegacyExamples/Examples/ImageGallery/ImageCells.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit class ImageCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! } class ScrollingImageCell: UICollectionViewCell { var imageView: UIImageView! var scrollView: UIScrollView! var dTapGR: UITapGestureRecognizer! var image: UIImage? { get { return imageView.image } set { imageView.image = newValue setNeedsLayout() } } var topInset: CGFloat = 0 { didSet { centerIfNeeded() } } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) scrollView = UIScrollView(frame: bounds) imageView = UIImageView(frame: bounds) imageView.contentMode = .scaleAspectFill scrollView.addSubview(imageView) scrollView.maximumZoomScale = 3 scrollView.delegate = self scrollView.contentMode = .center scrollView.showsHorizontalScrollIndicator = false scrollView.showsVerticalScrollIndicator = false #if os(tvOS) scrollView.panGestureRecognizer.allowedTouchTypes = [ NSNumber(value: UITouch.TouchType.indirect.rawValue) ] #endif addSubview(scrollView) dTapGR = UITapGestureRecognizer(target: self, action: #selector(doubleTap(gr:))) dTapGR.numberOfTapsRequired = 2 addGestureRecognizer(dTapGR) } func zoomRectForScale(scale: CGFloat, center: CGPoint) -> CGRect { var zoomRect = CGRect.zero zoomRect.size.height = imageView.frame.size.height / scale zoomRect.size.width = imageView.frame.size.width / scale let newCenter = imageView.convert(center, from: scrollView) zoomRect.origin.x = newCenter.x - (zoomRect.size.width / 2.0) zoomRect.origin.y = newCenter.y - (zoomRect.size.height / 2.0) return zoomRect } @objc func doubleTap(gr: UITapGestureRecognizer) { if scrollView.zoomScale == 1 { scrollView.zoom(to: zoomRectForScale(scale: scrollView.maximumZoomScale, center: gr.location(in: gr.view)), animated: true) } else { scrollView.setZoomScale(1, animated: true) } } override func layoutSubviews() { super.layoutSubviews() scrollView.frame = bounds let size: CGSize if let image = imageView.image { let containerSize = CGSize(width: bounds.width, height: bounds.height - topInset) if containerSize.width / containerSize.height < image.size.width / image.size.height { size = CGSize(width: containerSize.width, height: containerSize.width * image.size.height / image.size.width ) } else { size = CGSize(width: containerSize.height * image.size.width / image.size.height, height: containerSize.height ) } } else { size = CGSize(width: bounds.width, height: bounds.width) } imageView.frame = CGRect(origin: .zero, size: size) scrollView.contentSize = size centerIfNeeded() } override func prepareForReuse() { super.prepareForReuse() scrollView.setZoomScale(1, animated: false) } func centerIfNeeded() { var inset = UIEdgeInsets(top: topInset, left: 0, bottom: 0, right: 0) if scrollView.contentSize.height < scrollView.bounds.height - topInset { let insetV = (scrollView.bounds.height - topInset - scrollView.contentSize.height)/2 inset.top += insetV inset.bottom = insetV } if scrollView.contentSize.width < scrollView.bounds.width { let insetV = (scrollView.bounds.width - scrollView.contentSize.width)/2 inset.left = insetV inset.right = insetV } scrollView.contentInset = inset } } extension ScrollingImageCell: UIScrollViewDelegate { func viewForZooming(in scrollView: UIScrollView) -> UIView? { return imageView } func scrollViewDidZoom(_ scrollView: UIScrollView) { centerIfNeeded() } } #if !(swift(>=4.2)) extension UITouch { typealias TouchType = UITouchType } #endif ================================================ FILE: LegacyExamples/Examples/ImageGallery/ImageGallery.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/ImageGallery/ImageGalleryCollectionViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero class ImageGalleryViewController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! var columns = 3 lazy var cellSize: CGSize = CGSize(width: self.view.bounds.width/CGFloat(self.columns), height: self.view.bounds.width/CGFloat(self.columns)) override func viewDidLoad() { super.viewDidLoad() collectionView.reloadData() collectionView.indicatorStyle = .white } @IBAction func switchLayout(_ sender: Any) { // just replace the root view controller with the same view controller // animation is automatic! Holy let next = (UIStoryboard(name: "ImageGallery", bundle: nil).instantiateViewController(withIdentifier: "imageGallery") as? ImageGalleryViewController)! next.columns = columns == 3 ? 5 : 3 hero.replaceViewController(with: next) } } extension ImageGalleryViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let vc = (viewController(forStoryboardName: "ImageViewer") as? ImageViewController)! vc.selectedIndex = indexPath if let navigationController = navigationController { navigationController.pushViewController(vc, animated: true) } else { present(vc, animated: true, completion: nil) } } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return ImageLibrary.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let imageCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as? ImageCell)! imageCell.imageView.image = ImageLibrary.thumbnail(index:indexPath.item) imageCell.imageView.hero.id = "image_\(indexPath.item)" imageCell.imageView.hero.modifiers = [.fade, .scale(0.8)] imageCell.imageView.isOpaque = true return imageCell } } extension ImageGalleryViewController: UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return cellSize } } extension ImageGalleryViewController: HeroViewControllerDelegate { func heroWillStartAnimatingTo(viewController: UIViewController) { if (viewController as? ImageGalleryViewController) != nil { collectionView.hero.modifiers = [.cascade(delta:0.015, direction:.bottomToTop, delayMatchedViews:true)] } else if (viewController as? ImageViewController) != nil { let cell = collectionView.cellForItem(at: collectionView.indexPathsForSelectedItems!.first!)! collectionView.hero.modifiers = [.cascade(delta: 0.015, direction: .radial(center: cell.center), delayMatchedViews: true)] } else { collectionView.hero.modifiers = [.cascade(delta:0.015)] } } func heroWillStartAnimatingFrom(viewController: UIViewController) { view.hero.modifiers = nil if (viewController as? ImageGalleryViewController) != nil { collectionView.hero.modifiers = [.cascade(delta:0.015), .delay(0.25)] } else { collectionView.hero.modifiers = [.cascade(delta:0.015)] } if let vc = viewController as? ImageViewController, let originalCellIndex = vc.selectedIndex, let currentCellIndex = vc.collectionView?.indexPathsForVisibleItems[0], let targetAttribute = collectionView.layoutAttributesForItem(at: currentCellIndex) { collectionView.hero.modifiers = [.cascade(delta:0.015, direction:.inverseRadial(center:targetAttribute.center))] if !collectionView.indexPathsForVisibleItems.contains(currentCellIndex) { // make the cell visible collectionView.scrollToItem(at: currentCellIndex, at: originalCellIndex < currentCellIndex ? .bottom : .top, animated: false) } } } } ================================================ FILE: LegacyExamples/Examples/ImageGallery/ImageLibrary.swift ================================================ // // ImageLibrary.swift // HeroExamples // // Created by YiLun Zhao on 2017-01-04. // Copyright © 2017 Luke Zhao. All rights reserved. // import UIKit class ImageLibrary { static var count = 100 static func thumbnail(index: Int) -> UIImage { return UIImage(named: "Unsplash\(index % 11)_thumb")! } static func image(index: Int) -> UIImage { return UIImage(named: "Unsplash\(index % 11)")! } } ================================================ FILE: LegacyExamples/Examples/ImageGallery/ImageViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero class ImageViewController: UICollectionViewController { var selectedIndex: IndexPath? var panGR = UIPanGestureRecognizer() override func viewDidLoad() { super.viewDidLoad() automaticallyAdjustsScrollViewInsets = false preferredContentSize = CGSize(width: view.bounds.width, height: view.bounds.width) view.layoutIfNeeded() collectionView!.reloadData() if let selectedIndex = selectedIndex { collectionView!.scrollToItem(at: selectedIndex, at: .centeredHorizontally, animated: false) } panGR.addTarget(self, action: #selector(pan)) panGR.delegate = self collectionView?.addGestureRecognizer(panGR) } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() for v in (collectionView!.visibleCells as? [ScrollingImageCell])! { v.topInset = topLayoutGuide.length } } @objc func pan() { let translation = panGR.translation(in: nil) let progress = translation.y / 2 / collectionView!.bounds.height switch panGR.state { case .began: hero.dismissViewController() case .changed: Hero.shared.update(progress) if let cell = collectionView?.visibleCells[0] as? ScrollingImageCell { let currentPos = CGPoint(x: translation.x + view.center.x, y: translation.y + view.center.y) Hero.shared.apply(modifiers: [.position(currentPos)], to: cell.imageView) } default: if progress + panGR.velocity(in: nil).y / collectionView!.bounds.height > 0.3 { Hero.shared.finish() } else { Hero.shared.cancel() } } } } extension ImageViewController { override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return ImageLibrary.count } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let imageCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as? ScrollingImageCell)! imageCell.image = ImageLibrary.image(index:indexPath.item) imageCell.imageView.hero.id = "image_\(indexPath.item)" imageCell.imageView.hero.modifiers = [.position(CGPoint(x:view.bounds.width/2, y:view.bounds.height+view.bounds.width/2)), .scale(0.6), .fade] imageCell.topInset = topLayoutGuide.length imageCell.imageView.isOpaque = true return imageCell } } extension ImageViewController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return view.bounds.size } } extension ImageViewController:UIGestureRecognizerDelegate { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { if let cell = collectionView?.visibleCells[0] as? ScrollingImageCell, cell.scrollView.zoomScale == 1 { let v = panGR.velocity(in: nil) return v.y > abs(v.x) } return false } } ================================================ FILE: LegacyExamples/Examples/ImageGallery/ImageViewer.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/ListToGrid/GridCollectionViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero import ChameleonFramework class GridImageCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var textLabel: UILabel! @IBOutlet weak var detailTextLabel: UILabel! } class GridCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { @IBAction func toList(_ sender: Any) { let next = (UIStoryboard(name: "ListToGrid", bundle: nil).instantiateViewController(withIdentifier: "list") as? ListTableViewController)! next.tableView.contentOffset.y = collectionView!.contentOffset.y + collectionView!.contentInset.top hero.replaceViewController(with: next) } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return ImageLibrary.count } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: view.frame.width / 3, height: 52*3) } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as? GridImageCell)! let image = ImageLibrary.thumbnail(index:indexPath.item) cell.hero.modifiers = [.fade, .translate(y:20)] cell.imageView!.image = image cell.imageView!.hero.id = "image_\(indexPath.item)" cell.imageView!.hero.modifiers = [.arc] cell.imageView!.isOpaque = true cell.textLabel!.text = "Item \(indexPath.item)" cell.detailTextLabel!.text = "Description \(indexPath.item)" cell.backgroundColor = UIColor(averageColorFrom: image) return cell } override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let vc = (viewController(forStoryboardName: "ImageViewer") as? ImageViewController)! vc.selectedIndex = indexPath vc.view.backgroundColor = UIColor.white vc.collectionView!.backgroundColor = UIColor.white navigationController!.pushViewController(vc, animated: true) } } extension GridCollectionViewController: HeroViewControllerDelegate { func heroWillStartAnimatingTo(viewController: UIViewController) { if let _ = viewController as? ImageViewController, let index = collectionView!.indexPathsForSelectedItems?[0], let cell = collectionView!.cellForItem(at: index) as? GridImageCell { let cellPos = view.convert(cell.imageView.center, from: cell) collectionView!.hero.modifiers = [.scale(3), .translate(x:view.center.x - cellPos.x, y:view.center.y + collectionView!.contentInset.top/2/3 - cellPos.y), .ignoreSubviewModifiers, .fade] } else { collectionView!.hero.modifiers = [.cascade] } } func heroWillStartAnimatingFrom(viewController: UIViewController) { if let vc = viewController as? ImageViewController, let originalCellIndex = vc.selectedIndex, let currentCellIndex = vc.collectionView?.indexPathsForVisibleItems[0] { collectionView!.hero.modifiers = [.cascade] if !collectionView!.indexPathsForVisibleItems.contains(currentCellIndex) { // make the cell visible collectionView!.scrollToItem(at: currentCellIndex, at: originalCellIndex < currentCellIndex ? .bottom : .top, animated: false) } } else { collectionView!.hero.modifiers = [.cascade, .delay(0.2)] } } } ================================================ FILE: LegacyExamples/Examples/ListToGrid/ListTableViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero class ListTableViewCell: UITableViewCell { override func layoutSubviews() { super.layoutSubviews() imageView?.frame.origin.x = 0 imageView?.frame.size = CGSize(width: bounds.height, height: bounds.height) textLabel?.frame.origin.x = bounds.height + 10 detailTextLabel?.frame.origin.x = bounds.height + 10 } } class ListTableViewController: UITableViewController { override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return ImageLibrary.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "item", for: indexPath) cell.hero.modifiers = [.fade, .translate(x:-100)] cell.imageView!.hero.id = "image_\(indexPath.item)" cell.imageView!.hero.modifiers = [.arc] cell.imageView!.image = ImageLibrary.thumbnail(index:indexPath.item) cell.imageView!.isOpaque = true cell.textLabel!.text = "Item \(indexPath.item)" cell.detailTextLabel!.text = "Description \(indexPath.item)" return cell } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 52 } @IBAction func toGrid(_ sender: Any) { let next = (UIStoryboard(name: "ListToGrid", bundle: nil).instantiateViewController(withIdentifier: "grid") as? GridCollectionViewController)! next.collectionView?.contentOffset.y = tableView.contentOffset.y + tableView.contentInset.top hero.replaceViewController(with: next) } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let vc = (viewController(forStoryboardName: "ImageViewer") as? ImageViewController)! vc.selectedIndex = indexPath vc.view.backgroundColor = UIColor.white vc.collectionView!.backgroundColor = UIColor.white navigationController!.pushViewController(vc, animated: true) } } extension ListTableViewController: HeroViewControllerDelegate { func heroWillStartAnimatingTo(viewController: UIViewController) { if let _ = viewController as? GridCollectionViewController { tableView.hero.modifiers = [.ignoreSubviewModifiers] } else if viewController is ImageViewController { } else { tableView.hero.modifiers = [.cascade] } } func heroWillStartAnimatingFrom(viewController: UIViewController) { if let _ = viewController as? GridCollectionViewController { tableView.hero.modifiers = [.ignoreSubviewModifiers] } else { tableView.hero.modifiers = [.cascade] } if let vc = viewController as? ImageViewController, let originalCellIndex = vc.selectedIndex, let currentCellIndex = vc.collectionView?.indexPathsForVisibleItems[0] { if tableView.indexPathsForVisibleRows?.contains(currentCellIndex) != true { // make the cell visible tableView.scrollToRow(at: currentCellIndex, at: originalCellIndex < currentCellIndex ? .bottom : .top, animated: false) } } } } ================================================ FILE: LegacyExamples/Examples/ListToGrid/ListToGrid.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/Menu/Menu.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/Menu/MenuViewController.swift ================================================ // // MenuViewController.swift // HeroExamples // // Created by YiLun Zhao on 2017-02-09. // Copyright © 2017 Luke Zhao. All rights reserved. // import UIKit import Hero class MenuViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dismissMenu))) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? MenuPageViewController, let sender = sender as? UIButton { sender.hero.id = "selected" vc.view.hero.modifiers = [.source(heroID: "selected")] vc.centerButton.hero.id = "selected" vc.centerButton.hero.modifiers = [.durationMatchLongest] vc.view.backgroundColor = sender.backgroundColor vc.centerButton.setImage(sender.image(for: .normal), for: .normal) } } @objc private func dismissMenu() { hero.dismissViewController() } } class MenuPageViewController: UIViewController { @IBOutlet weak var centerButton: UIButton! } ================================================ FILE: LegacyExamples/Examples/MusicPlayer.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/Navigation/FirstViewController.swift ================================================ // // FirstViewController.swift // HeroExamples // // Created by Luke Zhao on 2017-11-04. // Copyright © 2017 Luke Zhao. All rights reserved. // import UIKit class FirstViewController: UIViewController { @IBAction func toggleIsHeroEnabled(_ sender: UISwitch) { // uncomment the following code to configure different animation type // navigationController?.heroNavigationAnimationType = .zoomOut navigationController?.hero.isEnabled = sender.isOn } } ================================================ FILE: LegacyExamples/Examples/Navigation/Navigation.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/VideoPlayer/VideoPlayer.storyboard ================================================ ================================================ FILE: LegacyExamples/Examples/VideoPlayer/VideoPlayerViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero import AVKit import AVFoundation class AVPlayerView: UIView { override class var layerClass: Swift.AnyClass { return AVPlayerLayer.self } } class VideoPlayerViewController: UIViewController { var playerView: UIView! var panGR: UIPanGestureRecognizer! override func viewDidLoad() { super.viewDidLoad() let player = AVPlayer(url: URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!) playerView = AVPlayerView(frame: view.bounds) playerView.backgroundColor = .black (playerView.layer as! AVPlayerLayer).player = player playerView.hero.id = "videoPlayer" playerView.hero.modifiers = [.useNoSnapshot] view.insertSubview(playerView, at: 0) panGR = UIPanGestureRecognizer(target: self, action: #selector(pan)) view.addGestureRecognizer(panGR) // skip the initial splash screen of the video player.seek(to: CMTimeMakeWithSeconds(0.35, preferredTimescale: 1000), toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) player.play() } @objc func pan() { let translation = panGR.translation(in: nil) let progress = translation.y / view.bounds.height switch panGR.state { case .began: hero.dismissViewController() case .changed: Hero.shared.update(progress) let currentPos = CGPoint(x: translation.x + view.center.x, y: translation.y + view.center.y) Hero.shared.apply(modifiers: [.position(currentPos)], to: playerView) default: if progress + panGR.velocity(in: nil).y / view.bounds.height > 0.3 { Hero.shared.finish() } else { Hero.shared.cancel() } } } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() playerView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.width / 16 * 9) playerView.center = view.center } } ================================================ FILE: LegacyExamples/LegacyExampleViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero class LegacyExampleViewController: UITableViewController { var storyboards: [[String]] = [ [], ["Basic", "Navigation", "MusicPlayer", "Menu", "BuiltInTransitions"], ["CityGuide", "ImageViewer", "VideoPlayer"], ["AppleHomePage", "ListToGrid", "ImageGallery"] ] override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: bottomLayoutGuide.length, right: 0) tableView.scrollIndicatorInsets = tableView.contentInset } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if indexPath.item < storyboards[indexPath.section].count { let storyboardName = storyboards[indexPath.section][indexPath.item] let vc = viewController(forStoryboardName: storyboardName) // iOS bug: https://github.com/lkzhao/Hero/issues/106 https://github.com/lkzhao/Hero/issues/79 DispatchQueue.main.async { self.present(vc, animated: true, completion: nil) } } } } ================================================ FILE: LegacyExamples/PluginViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero class PluginViewController: UIViewController { @IBOutlet weak var debugSwitch: UISwitch! @IBAction func togglePlugin(_ sender: UISwitch) { if sender == debugSwitch { HeroDebugPlugin.isEnabled = sender.isOn } } override func viewDidLoad() { super.viewDidLoad() debugSwitch.isOn = HeroDebugPlugin.isEnabled } } ================================================ FILE: LegacyExamples/en.lproj/Main.strings ================================================ /* Class = "UILabel"; text = "Built-in"; ObjectID = "IIL-pF-BfF"; */ "IIL-pF-BfF.text" = "Built-in"; /* Class = "UITabBarItem"; title = "Plugins"; ObjectID = "bDK-79-b3B"; */ "bDK-79-b3B.title" = "Plugins"; /* Class = "UILabel"; text = "HeroDebugPlugin"; ObjectID = "fUh-RG-Pga"; */ "fUh-RG-Pga.text" = "HeroDebugPlugin"; /* Class = "UIViewController"; title = "Plugins"; ObjectID = "uv4-Wk-GeR"; */ "uv4-Wk-GeR.title" = "Plugins"; ================================================ FILE: Makefile ================================================ GITHUB_URL := https://github.com/HeroTransitions/Hero/ include .makefiles/ludicrous.mk include .makefiles/bundler.mk include .makefiles/ios.mk PLATFORM := 'iOS' TEST_SCHEME := 'HeroExamples' WORKSPACE := 'Hero.xcworkspace' %: @: args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}` #> Lint the podspec for upload pod_lint: bundle exec pod spec lint Hero.podspec #> Build API documentation; https://github.com/realm/jazzy jazzy: @jazzy --config .jazzy.yaml #> Markdown API using sourcedocs; https://github.com/eneko/SourceDocs sourcedocs: @sourcedocs generate --clean --output-folder docs #> Run tests swift_test: swift test --parallel #> Build debug swift_debug: swift build --skip-update --jobs 4 --configuration debug #> Build release swift_release: swift build --skip-update --jobs 4 --configuration release ================================================ FILE: Mintfile ================================================ # yonaskolb/xcodegen realm/SwiftLint # Linting Tool danger/swift.git nicklockwood/SwiftFormat # orta/Komondor ================================================ FILE: Package.md ================================================ # Package: **Hero** ## Products List of products in this package: | Product | Type | Targets | | ------- | ---- | ------- | | Hero | library | Hero | _Libraries denoted 'automatic' can be both static or dynamic._ ## Modules ### Program Modules | Module | Type | Dependencies | | ------ | ---- | ------------ | | Hero | Regular | | ### Test Modules | Module | Type | Dependencies | | ------ | ---- | ------------ | | HeroTests | Test | | ## External Dependencies This package has zero dependencies 🎉 ## Requirements ### Minimum Required Versions | Platform | Version | | -------- | ------- | | tvOS | 10.0 | | iOS | 10.0 | This file was generated by [SourceDocs](https://github.com/eneko/SourceDocs) on 2024-02-06 02:01:40 +0000 ================================================ FILE: Package.swift ================================================ // swift-tools-version:5.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "Hero", platforms: [ .tvOS(.v10), .iOS(.v10) ], products: [ .library(name: "Hero", targets: ["Hero"]), ], targets: [ .target(name: "Hero", path: "Sources"), .testTarget(name: "HeroTests", dependencies: [.target(name: "Hero")], path: "Tests"), ], swiftLanguageVersions: [.v5] ) // The settings for the git hooks for our repo #if canImport(PackageConfig) import PackageConfig let config = PackageConfig([ "komondor": [ // When someone has run `git commit`, first run // SwiftFormat and the auto-correcter for SwiftLint "pre-commit": [ "swift run swiftformat .", "swift run swiftlint autocorrect", "git add .", ], ] ]) #endif ================================================ FILE: PackageModules.dot ================================================ digraph ModuleDependencyGraph { rankdir = LR graph [fontname="Helvetica-light", style = filled, color = "#eaeaea"] node [shape=box, fontname="Helvetica", style=filled] edge [color="#545454"] subgraph clusterRegular { label = "Program Modules" node [color="#caecec"] "Hero" } subgraph clusterTest { label = "Test Modules" node [color="#aaccee"] "HeroTests" } subgraph clusterExternal { label = "External Dependencies" node [color="#eeccaa"] "" } "HeroTests" -> "" } ================================================ FILE: Podfile ================================================ target 'HeroExamples' do platform :ios, '10.0' use_frameworks! pod 'CollectionKit', :inhibit_warnings => true target 'HeroTests' do inherit! :search_paths end end target 'HeroTvOSExamples' do platform :tvos, '10.0' use_frameworks! end ================================================ FILE: README.md ================================================ **Hero** is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit's cumbersome transition APIs—making custom transitions an easy task for developers. [![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) [![Accio supported](https://img.shields.io/badge/Accio-supported-0A7CF5.svg?style=flat)](https://github.com/JamitLabs/Accio) [![codecov](https://codecov.io/gh/HeroTransitions/Hero/branch/develop/graph/badge.svg)](https://codecov.io/gh/HeroTransitions/Hero) [![Version](https://img.shields.io/cocoapods/v/Hero.svg?style=flat)](http://cocoapods.org/pods/Hero) [![License](https://img.shields.io/cocoapods/l/Hero.svg?style=flat)](https://github.com/lkzhao/Hero/blob/master/LICENSE?raw=true) ![Xcode 10.0+](https://img.shields.io/badge/Xcode-10.0%2B-blue.svg) ![iOS 10.0+](https://img.shields.io/badge/iOS-10.0%2B-blue.svg) ![Swift 4.0+](https://img.shields.io/badge/Swift-4.0%2B-orange.svg) [![中文 README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-blue.svg?style=flat)](https://github.com/lkzhao/Hero/blob/master/README.zh-cn.md) [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=NT5F7Y2MPV7RE) [![Unit Test](https://github.com/HeroTransitions/Hero/actions/workflows/test.yml/badge.svg)](https://github.com/HeroTransitions/Hero/actions/workflows/test.yml) [![Swift PM](https://github.com/HeroTransitions/SwiftPMTest/actions/workflows/spm.yml/badge.svg)](https://github.com/HeroTransitions/SwiftPMTest/actions/workflows/spm.yml)        Hero is similar to Keynote's **Magic Move**. It checks the `heroID` property on all source and destination views. Every matched view pair is then automatically transitioned from its old state to its new state. Hero can also construct animations for unmatched views. It is easy to define these animations via the `heroModifiers` property. Hero will run these animations alongside the **Magic Move** animations. All of these animations can be **interactively controlled** by user gestures. At view controller level, Hero provides several template transitions that you can set through `heroModalAnimationType`, `heroNavigationAnimationType`, and `heroTabBarAnimationType`. These can be used as the foundation of your custom transitions. Combine with `heroID` & `heroModifiers` to make your own unique transitions.        By default, Hero provides **dynamic duration** based on the [Material Design Motion Guide](https://material.io/design/motion/speed.html#easing). Duration is automatically determined by changes to distance and size—saving you the hassle, while providing consistent and delightful animations. Hero doesn't make any assumptions about how the view is built or structured. It won't modify any of your views' states other than hiding them during the animation. This makes it work with **Auto Layout**, **programmatic layout**, **UICollectionView** (without modifying its layout object), **UITableView**, **UINavigationController**, **UITabBarController**, etc... ## Usage Example 1 ### View Controller 1 ```swift redView.hero.id = "ironMan" blackView.hero.id = "batMan" ``` ### View Controller 2 ```swift self.hero.isEnabled = true redView.hero.id = "ironMan" blackView.hero.id = "batMan" whiteView.hero.modifiers = [.translate(y:100)] ``` ## Usage Example 2 ### View Controller 1 ```swift greyView.hero.id = "skyWalker" ``` ### View Controller 2 ```swift self.hero.isEnabled = true greyView.hero.id = "skyWalker" // collectionView is the parent view of all red cells collectionView.hero.modifiers = [.cascade] for cell in redCells { cell.hero.modifiers = [.fade, .scale(0.5)] } ``` You can do these in the **storyboard** too! ## Installation ### CocoaPods Add the following entry to your Podfile: ```rb pod 'Hero' ``` Then run `pod install`. Don't forget to `import Hero` in every file you'd like to use Hero. ### Carthage Add the following entry to your `Cartfile`: ```text github "HeroTransitions/Hero" ``` Then run `carthage update`. If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained [over at Carthage](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). ### Accio Add the following to your `Package.swift`: ```swift .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.4.0")), ``` Next, add `Hero` to your App targets dependencies like so: ```swift .target( name: "App", dependencies: [ "Hero", ] ), ``` Then run `accio update`. ### Swift Package Manager To integrate using Apple's Swift package manager, add the following as a dependency to your `Package.swift`: ```swift .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.3.0")) ``` and then specify `"Hero"` as a dependency of the Target in which you wish to use Hero. Here's an example `PackageDescription`: ```swift // swift-tools-version:4.0 import PackageDescription let package = Package( name: "MyPackage", products: [ .library( name: "MyPackage", targets: ["MyPackage"]), ], dependencies: [ .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.6.3")) ], targets: [ .target( name: "MyPackage", dependencies: ["Hero"]) ] ) ``` ### Manually - Drag the **Sources** folder anywhere in your project. ## Documentations Checkout the **[WIKI PAGES (Usage Guide)](https://github.com/lkzhao/Hero/wiki/Usage-Guide)** for documentations. For more up-to-date ones, please see the header-doc. (use **alt+click** in Xcode) Dash compatible API docs: https://HeroTransitions.github.io/Hero/ ## Interactive Transition Tutorials [Interactive transitions with Hero (Part 1)](https://lkzhao.gitbooks.io/hero/content/docs/InteractiveTransition.html) ## FAQ ### Not able to use Hero transition even when `self.hero.isEnabled` is set to true Make sure that you have also enabled `self.hero.isEnabled` on the navigation controller if you are doing a push/pop inside the navigation controller. ### Views being covered by another matched view during the transition Matched views use global coordinate space while unmatched views use local coordinate space by default. Local coordinate spaced views might be covered by other global coordinate spaced views. To solve this, use the `useGlobalCoordinateSpace` modifier on the views being covered. Checkout [Coordinate Space Wiki page](https://github.com/lkzhao/Hero/wiki/Coordinate-Space) for details. ### Push animation is shown along side my custom animation This is the default animation for navigation controller provided by Hero. To disable the push animation, set `self.hero.navigationAnimationType` to `.fade` or `.none` on the navigation controller. ### How do I use a different default animation when dismissing You can use the animation type `.selectBy(presenting:dismissing)` to specify a different default animation for dismiss. For example: ```swift self.hero.modalAnimationType = .selectBy(presenting:.zoom, dismissing:.zoomOut) ``` ## Contribute We welcome any contributions. Please read the [Contribution Guide](https://github.com/lkzhao/Hero/wiki/Contribution-Guide). ================================================ FILE: README.zh-cn.md ================================================ [![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) [![Version](https://img.shields.io/cocoapods/v/Hero.svg?style=flat)](http://cocoapods.org/pods/Hero) [![License](https://img.shields.io/cocoapods/l/Hero.svg?style=flat)](https://github.com/lkzhao/Hero/blob/master/LICENSE?raw=true) ![Xcode 8.2+](https://img.shields.io/badge/Xcode-8.2%2B-blue.svg) ![iOS 8.0+](https://img.shields.io/badge/iOS-8.0%2B-blue.svg) ![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg) **Hero**是一个iOS界面切换库。它代替了UIKit本身的转场动画接口,使制作自定义的转场动画(View Controller Transition)非常简单! ### 特点        #### 你可以使用这些效果来拼凑出你想要的转场动画。 Hero很像Keynote的[“神奇移动”过渡(Magic Move)](https://support.apple.com/kb/PH16959?locale=zh_CN)。在界面切换时,Hero会把开始界面的视图与结束界面的视图配对,假如他能找到一对儿有着一样的`heroID`的视图的话,Hero便会自动为此视图创建动画,从它一开始的状态移动到结束时的状态。 不仅如此,Hero还可以为没有配对的视图制作动画。每一个视图都可以轻易的用`heroModifiers`来告诉Hero你想为这个视图所创造的动画。交互式动画(interactive transition)也是支持的哟。 Hero还参照Google的[Material Design Motion Guide](https://material.io/guidelines/motion/duration-easing.html)来提供动态的动画长度。你不需要告诉Hero动画时间,Hero会参照视图的移动长度和大小来自动选择最适合的参数。 无论你使用怎样的方法制作和布局你的视图,Hero都能帮你省去很多时间制作动画。Hero支持 **auto layout**, **programmatic layout**, **UICollectionView**, **UITableView**, **UINavigationController**, **UITabBarController**, 等等。。 ### 还有 从**0.3.0**开始. Hero自带许多转场动画. 这些自带的转场动画可以与你的`heroID` & `heroModifiers`结合,搭配出简单却又独一无二的动画。        ## 效果 请看[Example Gallery Blog Post](http://lkzhao.com/2016/12/28/hero.html)来了解Hero具体能做出什么样的效果 ## 安装方法与用法 Hero可以用Carthage或者Cocoapods安装,具体用法请见**[Usage Guide](https://github.com/lkzhao/Hero/wiki/Usage-Guide)**。 ##### 注: 因为一个苹果的[bug](https://forums.developer.apple.com/thread/63438),Hero 不能在iPhone 7 Simulators上使用。 请使用其他版本的Simulator或者使用真机。 ## 简单实例 1 ##### View Controller 1 ```swift redView.hero.id = "ironMan" blackView.hero.id = "batMan" ``` ##### View Controller 2 ```swift self.hero.isEnabled = true redView.hero.id = "ironMan" blackView.hero.id = "batMan" whiteView.hero.modifiers = [.translate(y:100)] ``` ## 简单实例 2 ##### View Controller 1 ```swift greyView.hero.id = "skyWalker" ``` ##### View Controller 2 ```swift self.hero.isEnabled = true greyView.hero.id = "skyWalker" // collectionView is the parent view of all red cells collectionView.hero.modifiers = [.cascade] for cell in redCells { cell.hero.modifiers = [.fade, .scale(0.5)] } ``` Hero 还支持 **storyboard**。 你可以在Storyboard右边的Identity Inspector来使用HeroID与HeroModifiers。 ## Contribute We welcome any contributions. Please read the [Contribution Guide](https://github.com/lkzhao/Hero/wiki/Contribution-Guide). ## License Hero is available under the MIT license. See the LICENSE file for more info. ================================================ FILE: Sources/Animator/HeroAnimatorViewContext.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit internal class HeroAnimatorViewContext { weak var animator: HeroAnimator? let snapshot: UIView let appearing: Bool var targetState: HeroTargetState var duration: TimeInterval = 0 // computed var currentTime: TimeInterval { return snapshot.layer.convertTime(CACurrentMediaTime(), from: nil) } var container: UIView? { return animator?.hero.context.container } class func canAnimate(view: UIView, state: HeroTargetState, appearing: Bool) -> Bool { return false } func apply(state: HeroTargetState) { } func changeTarget(state: HeroTargetState, isDestination: Bool) { } func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { return 0 } func seek(timePassed: TimeInterval) { } func clean() { animator = nil } func startAnimations() -> TimeInterval { return 0 } required init(animator: HeroAnimator, snapshot: UIView, targetState: HeroTargetState, appearing: Bool) { self.animator = animator self.snapshot = snapshot self.targetState = targetState self.appearing = appearing } } #endif ================================================ FILE: Sources/Animator/HeroCoreAnimationViewContext.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension CALayer { internal static var heroAddedAnimations: [(CALayer, String, CAAnimation)]? = { let swizzling: (AnyClass, Selector, Selector) -> Void = { forClass, originalSelector, swizzledSelector in if let originalMethod = class_getInstanceMethod(forClass, originalSelector), let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) { method_exchangeImplementations(originalMethod, swizzledMethod) } } let originalSelector = #selector(add(_:forKey:)) let swizzledSelector = #selector(hero_add(anim:forKey:)) swizzling(CALayer.self, originalSelector, swizzledSelector) return nil }() @objc dynamic func hero_add(anim: CAAnimation, forKey: String?) { if let animationKey = forKey, CALayer.heroAddedAnimations != nil, let copiedAnim = anim.copy() as? CAAnimation { copiedAnim.delegate = nil // having delegate resulted some weird animation behavior CALayer.heroAddedAnimations?.append((self, animationKey, copiedAnim)) } hero_add(anim: anim, forKey: forKey) } } internal class HeroCoreAnimationViewContext: HeroAnimatorViewContext { var state = [String: (Any?, Any?)]() var timingFunction: CAMediaTimingFunction = .standard var animations: [(CALayer, String, CAAnimation)] = [] // computed var contentLayer: CALayer? { let firstLayer = snapshot.layer.sublayers?.get(0) if firstLayer?.bounds == snapshot.bounds { return firstLayer } return nil } var overlayLayer: CALayer? override class func canAnimate(view: UIView, state: HeroTargetState, appearing: Bool) -> Bool { return state.position != nil || state.size != nil || state.transform != nil || state.cornerRadius != nil || state.opacity != nil || state.overlay != nil || state.anchorPoint != nil || state.backgroundColor != nil || state.borderColor != nil || state.borderWidth != nil || state.shadowOpacity != nil || state.shadowRadius != nil || state.shadowOffset != nil || state.shadowColor != nil || state.shadowPath != nil || state.contentsRect != nil || state.forceAnimate } func getOverlayLayer() -> CALayer { if overlayLayer == nil { overlayLayer = CALayer() overlayLayer!.frame = snapshot.bounds overlayLayer!.opacity = 0 snapshot.layer.addSublayer(overlayLayer!) } return overlayLayer! } func overlayKeyFor(key: String) -> String? { if key.hasPrefix("overlay.") { var key = key key.removeSubrange(key.startIndex.. Any? { if let key = overlayKeyFor(key: key) { return (overlayLayer?.presentation() ?? overlayLayer)?.value(forKeyPath: key) } if snapshot.layer.animationKeys()?.isEmpty != false { return snapshot.layer.value(forKeyPath: key) } return (snapshot.layer.presentation() ?? snapshot.layer).value(forKeyPath: key) } func getAnimation(key: String, beginTime: TimeInterval, duration: TimeInterval, fromValue: Any?, toValue: Any?, ignoreArc: Bool = false) -> CAPropertyAnimation { let key = overlayKeyFor(key: key) ?? key let anim: CAPropertyAnimation if !ignoreArc, key == "position", let arcIntensity = targetState.arc, let fromPos = (fromValue as? NSValue)?.cgPointValue, let toPos = (toValue as? NSValue)?.cgPointValue, abs(fromPos.x - toPos.x) >= 1, abs(fromPos.y - toPos.y) >= 1 { let kanim = CAKeyframeAnimation(keyPath: key) let path = CGMutablePath() let maxControl = fromPos.y > toPos.y ? CGPoint(x: toPos.x, y: fromPos.y) : CGPoint(x: fromPos.x, y: toPos.y) let minControl = (toPos - fromPos) / 2 + fromPos path.move(to: fromPos) path.addQuadCurve(to: toPos, control: minControl + (maxControl - minControl) * arcIntensity) kanim.values = [fromValue!, toValue!] kanim.path = path kanim.duration = duration kanim.timingFunctions = [timingFunction] anim = kanim } else if #available(iOS 9.0, *), key != "cornerRadius", let (stiffness, damping) = targetState.spring { let sanim = CASpringAnimation(keyPath: key) sanim.stiffness = stiffness sanim.damping = damping sanim.duration = sanim.settlingDuration sanim.fromValue = fromValue sanim.toValue = toValue anim = sanim } else { let banim = CABasicAnimation(keyPath: key) banim.duration = duration banim.fromValue = fromValue banim.toValue = toValue banim.timingFunction = timingFunction anim = banim } anim.fillMode = CAMediaTimingFillMode.both anim.isRemovedOnCompletion = false anim.beginTime = beginTime return anim } func setSize(view: UIView, newSize: CGSize) { let oldSize = view.bounds.size if targetState.snapshotType != .noSnapshot { if oldSize.width == 0 || oldSize.height == 0 || newSize.width == 0 || newSize.height == 0 { for subview in view.subviews { subview.center = newSize.center subview.bounds.size = newSize setSize(view: subview, newSize: newSize) } } else { let sizeRatio = oldSize / newSize for subview in view.subviews { let center = subview.center let size = subview.bounds.size subview.center = center / sizeRatio subview.bounds.size = size / sizeRatio setSize(view: subview, newSize: size / sizeRatio) } } view.bounds.size = newSize } else { view.bounds.size = newSize view.layoutSubviews() } } func uiViewBasedAnimate(duration: TimeInterval, delay: TimeInterval, _ animations: @escaping () -> Void) { CALayer.heroAddedAnimations = [] if let (stiffness, damping) = targetState.spring { UIView.animate(withDuration: duration, delay: delay, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [], animations: animations, completion: nil) let addedAnimations = CALayer.heroAddedAnimations! CALayer.heroAddedAnimations = nil for (layer, key, anim) in addedAnimations { layer.removeAnimation(forKey: key) if #available(iOS 9.0, *), let anim = anim as? CASpringAnimation { anim.stiffness = stiffness anim.damping = damping self.addAnimation(anim, for: key, to: layer) } else { self.addAnimation(anim, for: key, to: layer) } } } else { CATransaction.begin() CATransaction.setAnimationTimingFunction(timingFunction) UIView.animate(withDuration: duration, delay: delay, options: [], animations: animations, completion: nil) let addedAnimations = CALayer.heroAddedAnimations! CALayer.heroAddedAnimations = nil for (layer, key, anim) in addedAnimations { layer.removeAnimation(forKey: key) self.addAnimation(anim, for: key, to: layer) } CATransaction.commit() } } func addAnimation(_ animation: CAAnimation, for key: String, to layer: CALayer) { let heroAnimationKey = "hero.\(key)" animations.append((layer, heroAnimationKey, animation)) layer.add(animation, forKey: heroAnimationKey) } // return the completion duration of the animation (duration + initial delay, not counting the beginTime) func animate(key: String, beginTime: TimeInterval, duration: TimeInterval, fromValue: Any?, toValue: Any?) -> TimeInterval { let anim = getAnimation(key: key, beginTime: beginTime, duration: duration, fromValue: fromValue, toValue: toValue) if let overlayKey = overlayKeyFor(key: key) { addAnimation(anim, for: overlayKey, to: getOverlayLayer()) } else { switch key { case "cornerRadius", "contentsRect", "contentsScale": addAnimation(anim, for: key, to: snapshot.layer) if let contentLayer = contentLayer { // swiftlint:disable:next force_cast addAnimation(anim.copy() as! CAAnimation, for: key, to: contentLayer) } if let overlayLayer = overlayLayer { // swiftlint:disable:next force_cast addAnimation(anim.copy() as! CAAnimation, for: key, to: overlayLayer) } case "bounds.size": guard let fromSize = (fromValue as? NSValue)?.cgSizeValue, let toSize = (toValue as? NSValue)?.cgSizeValue else { addAnimation(anim, for: key, to: snapshot.layer) break } setSize(view: snapshot, newSize: fromSize) uiViewBasedAnimate(duration: anim.duration, delay: beginTime - currentTime) { self.setSize(view: self.snapshot, newSize: toSize) } default: addAnimation(anim, for: key, to: snapshot.layer) } } return anim.duration + anim.beginTime - beginTime } /** - Returns: a CALayer [keyPath:value] map for animation */ func viewState(targetState: HeroTargetState) -> [String: Any?] { var targetState = targetState var rtn = [String: Any?]() if let size = targetState.size { if targetState.useScaleBasedSizeChange ?? self.targetState.useScaleBasedSizeChange ?? false { let currentSize = snapshot.bounds.size targetState.append(.scale(x: size.width / currentSize.width, y: size.height / currentSize.height)) } else { rtn["bounds.size"] = NSValue(cgSize: size) } } if let position = targetState.position { rtn["position"] = NSValue(cgPoint: position) } if let opacity = targetState.opacity, !(snapshot is UIVisualEffectView) { rtn["opacity"] = NSNumber(value: opacity) } if let cornerRadius = targetState.cornerRadius { rtn["cornerRadius"] = NSNumber(value: cornerRadius.native) } if let backgroundColor = targetState.backgroundColor { rtn["backgroundColor"] = backgroundColor } if let zPosition = targetState.zPosition { rtn["zPosition"] = NSNumber(value: zPosition.native) } if let anchorPoint = targetState.anchorPoint { rtn["anchorPoint"] = NSValue(cgPoint: anchorPoint) } if let borderWidth = targetState.borderWidth { rtn["borderWidth"] = NSNumber(value: borderWidth.native) } if let borderColor = targetState.borderColor { rtn["borderColor"] = borderColor } if let masksToBounds = targetState.masksToBounds { rtn["masksToBounds"] = masksToBounds } if targetState.displayShadow { if let shadowColor = targetState.shadowColor { rtn["shadowColor"] = shadowColor } if let shadowRadius = targetState.shadowRadius { rtn["shadowRadius"] = NSNumber(value: shadowRadius.native) } if let shadowOpacity = targetState.shadowOpacity { rtn["shadowOpacity"] = NSNumber(value: shadowOpacity) } if let shadowPath = targetState.shadowPath { rtn["shadowPath"] = shadowPath } if let shadowOffset = targetState.shadowOffset { rtn["shadowOffset"] = NSValue(cgSize: shadowOffset) } } if let contentsRect = targetState.contentsRect { rtn["contentsRect"] = NSValue(cgRect: contentsRect) } if let contentsScale = targetState.contentsScale { rtn["contentsScale"] = NSNumber(value: contentsScale.native) } if let transform = targetState.transform { rtn["transform"] = NSValue(caTransform3D: transform) } if let (color, opacity) = targetState.overlay { rtn["overlay.backgroundColor"] = color rtn["overlay.opacity"] = NSNumber(value: opacity.native) } return rtn } override func apply(state: HeroTargetState) { let targetState = viewState(targetState: state) for (key, targetValue) in targetState { if self.state[key] == nil { let current = currentValue(key: key) self.state[key] = (current, current) } let oldAnimations = animations animations = [] _ = animate(key: key, beginTime: 0, duration: 100, fromValue: targetValue, toValue: targetValue) animations = oldAnimations } } override func changeTarget(state: HeroTargetState, isDestination: Bool) { let targetState = viewState(targetState: state) for (key, targetValue) in targetState { let from: Any?, to: Any? if let data = self.state[key] { from = data.0 to = data.1 } else { let data = currentValue(key: key) from = data to = data } if isDestination { self.state[key] = (from, targetValue) } else { self.state[key] = (targetValue, to) } } } override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { for (key, (fromValue, toValue)) in state { let realToValue = !reverse ? toValue : fromValue let realFromValue = currentValue(key: key) state[key] = (realFromValue, realToValue) } if reverse { if timePassed > targetState.delay + duration { let backDelay = timePassed - (targetState.delay + duration) return animate(delay: backDelay, duration: duration) } else if timePassed > targetState.delay { return animate(delay: 0, duration: duration - (timePassed - targetState.delay)) } else { return 0 } } else { if timePassed <= targetState.delay { return animate(delay: targetState.delay - timePassed, duration: duration) } else if timePassed <= targetState.delay + duration { let timePassedDelay = timePassed - targetState.delay return animate(delay: 0, duration: duration - timePassedDelay) } else { return 0 } } } func animate(delay: TimeInterval, duration: TimeInterval) -> TimeInterval { for (layer, key, _) in animations { layer.removeAnimation(forKey: key) } if let tf = targetState.timingFunction { timingFunction = tf } var timeUntilStop: TimeInterval = duration animations = [] for (key, (fromValue, toValue)) in state { let neededTime = animate(key: key, beginTime: currentTime + delay, duration: duration, fromValue: fromValue, toValue: toValue) timeUntilStop = max(timeUntilStop, neededTime) } return timeUntilStop + delay } override func seek(timePassed: TimeInterval) { let timeOffset = timePassed - targetState.delay for (layer, key, anim) in animations { anim.speed = 0 anim.timeOffset = timeOffset.clamp(0, anim.duration - 0.001) layer.removeAnimation(forKey: key) layer.add(anim, forKey: key) } } override func clean() { super.clean() overlayLayer = nil } override func startAnimations() -> TimeInterval { if let beginStateModifiers = targetState.beginState { let beginState = HeroTargetState(modifiers: beginStateModifiers) let appeared = viewState(targetState: beginState) for (key, value) in appeared { snapshot.layer.setValue(value, forKeyPath: key) } if let (color, opacity) = beginState.overlay { let overlay = getOverlayLayer() overlay.backgroundColor = color overlay.opacity = Float(opacity) } } let disappeared = viewState(targetState: targetState) for (key, disappearedState) in disappeared { let appearingState = currentValue(key: key) let toValue = appearing ? appearingState : disappearedState let fromValue = !appearing ? appearingState : disappearedState state[key] = (fromValue, toValue) } return animate(delay: targetState.delay, duration: duration) } } #endif ================================================ FILE: Sources/Animator/HeroDefaultAnimator.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit internal extension UIView { func optimizedDurationTo(position: CGPoint?, size: CGSize?, transform: CATransform3D?) -> TimeInterval { let fromPos = (layer.presentation() ?? layer).position let toPos = position ?? fromPos let fromSize = (layer.presentation() ?? layer).bounds.size let toSize = size ?? fromSize let fromTransform = (layer.presentation() ?? layer).transform let toTransform = transform ?? fromTransform let realFromPos = CGPoint.zero.transform(fromTransform) + fromPos let realToPos = CGPoint.zero.transform(toTransform) + toPos let realFromSize = fromSize.transform(fromTransform) let realToSize = toSize.transform(toTransform) let movePoints = (realFromPos.distance(realToPos) + realFromSize.point.distance(realToSize.point)) // duration is 0.2 @ 0 to 0.375 @ 500 let duration = 0.208 + Double(movePoints.clamp(0, 500)) / 3000 return duration } } internal class HeroDefaultAnimator: HeroAnimator { weak public var hero: HeroTransition! public var context: HeroContext! { return hero?.context } var viewContexts: [UIView: ViewContext] = [:] public func seekTo(timePassed: TimeInterval) { for viewContext in viewContexts.values { viewContext.seek(timePassed: timePassed) } } public func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { var duration: TimeInterval = 0 for (_, viewContext) in viewContexts { if viewContext.targetState.duration == nil { viewContext.duration = max(viewContext.duration, calculateOptimizedDuration(snapshot: viewContext.snapshot, targetState: viewContext.targetState) + timePassed) } let timeUntilStopped = viewContext.resume(timePassed: timePassed, reverse: reverse) duration = max(duration, timeUntilStopped) } return duration } public func apply(state: HeroTargetState, to view: UIView) { if let context = viewContexts[view] { context.apply(state: state) } } public func changeTarget(state: HeroTargetState, isDestination: Bool, to view: UIView) { if let context = viewContexts[view] { context.changeTarget(state: state, isDestination: isDestination) } } public func canAnimate(view: UIView, appearing: Bool) -> Bool { guard let state = context[view] else { return false } return ViewContext.canAnimate(view: view, state: state, appearing: appearing) } public func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { var maxDuration: TimeInterval = 0 for v in fromViews { createViewContext(view: v, appearing: false) } for v in toViews { createViewContext(view: v, appearing: true) } for viewContext in viewContexts.values { if let duration = viewContext.targetState.duration, duration != .infinity { viewContext.duration = duration maxDuration = max(maxDuration, duration) } else { let duration = calculateOptimizedDuration(snapshot: viewContext.snapshot, targetState: viewContext.targetState) if viewContext.targetState.duration == nil { viewContext.duration = duration } maxDuration = max(maxDuration, duration) } } for viewContext in viewContexts.values { if viewContext.targetState.duration == .infinity { viewContext.duration = maxDuration } let timeUntilStopped = viewContext.startAnimations() maxDuration = max(maxDuration, timeUntilStopped) } return maxDuration } func calculateOptimizedDuration(snapshot: UIView, targetState: HeroTargetState) -> TimeInterval { return snapshot.optimizedDurationTo(position: targetState.position, size: targetState.size, transform: targetState.transform) } func createViewContext(view: UIView, appearing: Bool) { let snapshot = context.snapshotView(for: view) let viewContext = ViewContext(animator: self, snapshot: snapshot, targetState: context[view]!, appearing: appearing) viewContexts[view] = viewContext } public func clean() { for vc in viewContexts.values { vc.clean() } viewContexts.removeAll() } } #endif ================================================ FILE: Sources/Animator/HeroViewPropertyViewContext.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit @available(iOS 10, tvOS 10, *) internal class HeroViewPropertyViewContext: HeroAnimatorViewContext { var viewPropertyAnimator: UIViewPropertyAnimator! var endEffect: UIVisualEffect? var startEffect: UIVisualEffect? override class func canAnimate(view: UIView, state: HeroTargetState, appearing: Bool) -> Bool { return view is UIVisualEffectView && state.opacity != nil } override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { guard let visualEffectView = snapshot as? UIVisualEffectView else { return .zero } guard duration > 0 else { return .zero } if reverse { viewPropertyAnimator?.stopAnimation(false) viewPropertyAnimator?.finishAnimation(at: .current) viewPropertyAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { visualEffectView.effect = reverse ? self.startEffect : self.endEffect } // workaround for a bug https://openradar.appspot.com/30856746 viewPropertyAnimator.startAnimation() viewPropertyAnimator.pauseAnimation() viewPropertyAnimator.fractionComplete = CGFloat(1.0 - timePassed / duration) } DispatchQueue.main.async { self.viewPropertyAnimator.startAnimation() } return duration } override func seek(timePassed: TimeInterval) { viewPropertyAnimator?.pauseAnimation() viewPropertyAnimator?.fractionComplete = CGFloat(timePassed / duration) } override func clean() { super.clean() viewPropertyAnimator?.stopAnimation(false) viewPropertyAnimator?.finishAnimation(at: .current) viewPropertyAnimator = nil } override func startAnimations() -> TimeInterval { guard let visualEffectView = snapshot as? UIVisualEffectView else { return 0 } let appearedEffect = visualEffectView.effect let disappearedEffect = targetState.opacity == 0 ? nil : visualEffectView.effect startEffect = appearing ? disappearedEffect : appearedEffect endEffect = appearing ? appearedEffect : disappearedEffect visualEffectView.effect = startEffect viewPropertyAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { visualEffectView.effect = self.endEffect } viewPropertyAnimator.startAnimation() return duration } } #endif ================================================ FILE: Sources/Debug Plugin/HeroDebugPlugin.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) && os(iOS) import UIKit public class HeroDebugPlugin: HeroPlugin { public static var showOnTop: Bool = false var debugView: HeroDebugView? var zPositionMap = [UIView: CGFloat]() var addedLayers: [CALayer] = [] var updating = false override public func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { if hero.forceNotInteractive { return 0 } var hasArc = false for v in context.fromViews + context.toViews where context[v]?.arc != nil && context[v]?.position != nil { hasArc = true break } let debugView = HeroDebugView(initialProcess: hero.isPresenting ? 0.0 : 1.0, showCurveButton: hasArc, showOnTop: HeroDebugPlugin.showOnTop) debugView.frame = hero.container.bounds debugView.delegate = self hero.container.window?.addSubview(debugView) debugView.layoutSubviews() self.debugView = debugView UIView.animate(withDuration: 0.4) { debugView.showControls = true } return .infinity } public override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { guard let debugView = debugView else { return 0.4 } debugView.delegate = nil UIView.animate(withDuration: 0.4) { debugView.showControls = false debugView.debugSlider.setValue(roundf(debugView.progress), animated: true) } on3D(wants3D: false) return 0.4 } public override func clean() { debugView?.removeFromSuperview() debugView = nil } } extension HeroDebugPlugin: HeroDebugViewDelegate { public func onDone() { guard let debugView = debugView else { return } let seekValue = hero.isPresenting ? debugView.progress : 1.0 - debugView.progress if seekValue > 0.5 { hero.finish() } else { hero.cancel() } } public func onProcessSliderChanged(progress: Float) { let seekValue = hero.isPresenting ? progress : 1.0 - progress hero.update(CGFloat(seekValue)) } func onPerspectiveChanged(translation: CGPoint, rotation: CGFloat, scale: CGFloat) { var t = CATransform3DIdentity t.m34 = -1 / 4000 t = CATransform3DTranslate(t, translation.x, translation.y, 0) t = CATransform3DScale(t, scale, scale, 1) t = CATransform3DRotate(t, rotation, 0, 1, 0) hero.container.layer.sublayerTransform = t } func animateZPosition(view: UIView, to: CGFloat) { let a = CABasicAnimation(keyPath: "zPosition") a.fromValue = view.layer.value(forKeyPath: "zPosition") a.toValue = NSNumber(value: Double(to)) a.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) a.duration = 0.4 view.layer.add(a, forKey: "zPosition") view.layer.zPosition = to } func onDisplayArcCurve(wantsCurve: Bool) { for layer in addedLayers { layer.removeFromSuperlayer() addedLayers.removeAll() } if wantsCurve { for layer in hero.container.layer.sublayers! { for (_, anim) in layer.animations { if let keyframeAnim = anim as? CAKeyframeAnimation, let path = keyframeAnim.path { let s = CAShapeLayer() s.zPosition = layer.zPosition + 10 s.path = path s.strokeColor = UIColor.blue.cgColor s.fillColor = UIColor.clear.cgColor hero.container.layer.addSublayer(s) addedLayers.append(s) } } } } } func on3D(wants3D: Bool) { var t = CATransform3DIdentity if wants3D { var viewsWithZPosition = Set() for view in hero.container.subviews where view.layer.zPosition != 0 { viewsWithZPosition.insert(view) zPositionMap[view] = view.layer.zPosition } let viewsWithoutZPosition = hero.container.subviews.filter { return !viewsWithZPosition.contains($0) } let viewsWithPositiveZPosition = viewsWithZPosition.filter { return $0.layer.zPosition > 0 } for (i, v) in viewsWithoutZPosition.enumerated() { animateZPosition(view: v, to: CGFloat(i * 10)) } var maxZPosition: CGFloat = 0 for v in viewsWithPositiveZPosition { maxZPosition = max(maxZPosition, v.layer.zPosition) animateZPosition(view: v, to: v.layer.zPosition + CGFloat(viewsWithoutZPosition.count * 10)) } t.m34 = -1 / 4000 t = CATransform3DTranslate(t, debugView!.translation.x, debugView!.translation.y, 0) t = CATransform3DScale(t, debugView!.scale, debugView!.scale, 1) t = CATransform3DRotate(t, debugView!.rotation, 0, 1, 0) } else { for v in hero.container.subviews { animateZPosition(view: v, to: self.zPositionMap[v] ?? 0) } self.zPositionMap.removeAll() } let a = CABasicAnimation(keyPath: "sublayerTransform") a.fromValue = hero.container.layer.value(forKeyPath: "sublayerTransform") a.toValue = NSValue(caTransform3D: t) a.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) a.duration = 0.4 UIView.animate(withDuration: 0.4) { self.context.container.backgroundColor = UIColor(white: 0.85, alpha: 1.0) } hero.container.layer.add(a, forKey: "debug") hero.container.layer.sublayerTransform = t } } #endif ================================================ FILE: Sources/Debug Plugin/HeroDebugView.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) && os(iOS) import UIKit protocol HeroDebugViewDelegate: AnyObject { func onProcessSliderChanged(progress: Float) func onPerspectiveChanged(translation: CGPoint, rotation: CGFloat, scale: CGFloat) func on3D(wants3D: Bool) func onDisplayArcCurve(wantsCurve: Bool) func onDone() } class HeroDebugView: UIView { var backgroundView: UIView! var debugSlider: UISlider! var perspectiveButton: UIButton! var doneButton: UIButton! var arcCurveButton: UIButton? weak var delegate: HeroDebugViewDelegate? var panGR: UIPanGestureRecognizer! var pinchGR: UIPinchGestureRecognizer! var showControls: Bool = false { didSet { layoutSubviews() } } var showOnTop: Bool = false var rotation: CGFloat = π / 6 var scale: CGFloat = 0.6 var translation: CGPoint = .zero var progress: Float { return debugSlider.value } init(initialProcess: Float, showCurveButton: Bool, showOnTop: Bool) { super.init(frame: .zero) self.showOnTop = showOnTop backgroundView = UIView(frame: .zero) backgroundView.backgroundColor = UIColor(white: 1.0, alpha: 0.95) backgroundView.layer.shadowColor = UIColor.darkGray.cgColor backgroundView.layer.shadowOpacity = 0.3 backgroundView.layer.shadowRadius = 5 backgroundView.layer.shadowOffset = CGSize.zero addSubview(backgroundView) doneButton = UIButton(type: .system) doneButton.setTitle("Done", for: .normal) doneButton.addTarget(self, action: #selector(onDone), for: .touchUpInside) backgroundView.addSubview(doneButton) perspectiveButton = UIButton(type: .system) perspectiveButton.setTitle("3D View", for: .normal) perspectiveButton.addTarget(self, action: #selector(onPerspective), for: .touchUpInside) backgroundView.addSubview(perspectiveButton) if showCurveButton { arcCurveButton = UIButton(type: .system) arcCurveButton!.setTitle("Show Arcs", for: .normal) arcCurveButton!.addTarget(self, action: #selector(onDisplayArcCurve), for: .touchUpInside) backgroundView.addSubview(arcCurveButton!) } debugSlider = UISlider(frame: .zero) debugSlider.layer.zPosition = 1000 debugSlider.minimumValue = 0 debugSlider.maximumValue = 1 debugSlider.addTarget(self, action: #selector(onSlide), for: .valueChanged) debugSlider.isUserInteractionEnabled = true debugSlider.value = initialProcess backgroundView.addSubview(debugSlider) panGR = UIPanGestureRecognizer(target: self, action: #selector(pan)) panGR.delegate = self panGR.maximumNumberOfTouches = 1 addGestureRecognizer(panGR) pinchGR = UIPinchGestureRecognizer(target: self, action: #selector(pinch)) pinchGR.delegate = self addGestureRecognizer(pinchGR) } required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } public override func layoutSubviews() { super.layoutSubviews() var backgroundFrame = bounds let safeInset: CGFloat if #available(iOS 11.0, *) { safeInset = showOnTop ? safeAreaInsets.top : safeAreaInsets.bottom } else { safeInset = 0 } backgroundFrame.size.height = 72 + safeInset if showOnTop { backgroundFrame.origin.y = showControls ? 0 : -80 } else { backgroundFrame.origin.y = bounds.maxY - CGFloat(showControls ? 72.0 + safeInset : -8.0) } backgroundView.frame = backgroundFrame var sliderFrame = bounds.insetBy(dx: 10, dy: 0) sliderFrame.size.height = 44 sliderFrame.origin.y = showOnTop ? 28 + safeInset : 28 debugSlider.frame = sliderFrame perspectiveButton.sizeToFit() perspectiveButton.frame.origin = CGPoint(x: bounds.maxX - perspectiveButton.bounds.width - 10, y: showOnTop ? 4 + safeInset : 4) doneButton.sizeToFit() doneButton.frame.origin = CGPoint(x: 10, y: showOnTop ? 4 + safeInset : 4) arcCurveButton?.sizeToFit() arcCurveButton?.center = CGPoint(x: center.x, y: doneButton.center.y) } var startRotation: CGFloat = 0 @objc public func pan() { if panGR.state == .began { startRotation = rotation } rotation = startRotation + panGR.translation(in: nil).x / 150 if rotation > π { rotation -= 2 * π } else if rotation < -π { rotation += 2 * π } delegate?.onPerspectiveChanged(translation: translation, rotation: rotation, scale: scale) } var startLocation: CGPoint = .zero var startTranslation: CGPoint = .zero var startScale: CGFloat = 1 @objc public func pinch() { switch pinchGR.state { case .began: startLocation = pinchGR.location(in: nil) startTranslation = translation startScale = scale fallthrough case .changed: if pinchGR.numberOfTouches >= 2 { scale = min(1, max(0.2, startScale * pinchGR.scale)) translation = startTranslation + pinchGR.location(in: nil) - startLocation delegate?.onPerspectiveChanged(translation: translation, rotation: rotation, scale: scale) } default: break } } @objc public func onDone() { delegate?.onDone() } @objc public func onPerspective() { perspectiveButton.isSelected = !perspectiveButton.isSelected delegate?.on3D(wants3D: perspectiveButton.isSelected) } @objc public func onDisplayArcCurve() { arcCurveButton!.isSelected = !arcCurveButton!.isSelected delegate?.onDisplayArcCurve(wantsCurve: arcCurveButton!.isSelected) } @objc public func onSlide() { delegate?.onProcessSliderChanged(progress: debugSlider.value) } } extension HeroDebugView: UIGestureRecognizerDelegate { public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { return perspectiveButton.isSelected } } #endif ================================================ FILE: Sources/Extensions/Array+HeroModifier.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation #if canImport(CoreGraphics) import CoreGraphics #endif internal extension Array { func get(_ index: Int) -> Element? { if index < count { return self[index] } return nil } } internal extension Array where Element: ExprNode { #if canImport(CoreGraphics) func getCGFloat(_ index: Int) -> CGFloat? { if let s = get(index) as? NumberNode { return CGFloat(s.value) } return nil } #endif func getDouble(_ index: Int) -> Double? { if let s = get(index) as? NumberNode { return Double(s.value) } return nil } func getFloat(_ index: Int) -> Float? { if let s = get(index) as? NumberNode { return s.value } return nil } func getBool(_ index: Int) -> Bool? { if let s = get(index) as? VariableNode, let f = Bool(s.name) { return f } return nil } } ================================================ FILE: Sources/Extensions/CALayer+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit internal extension CALayer { // return all animations running by this layer. // the returned value is mutable var animations: [(String, CAAnimation)] { if let keys = animationKeys() { // swiftlint:disable:next force_cast return keys.map { return ($0, self.animation(forKey: $0)!.copy() as! CAAnimation) } } return [] } func flatTransformTo(layer: CALayer) -> CATransform3D { var layer = layer var trans = layer.transform while let superlayer = layer.superlayer, superlayer != self, !(superlayer.delegate is UIWindow) { trans = CATransform3DConcat(superlayer.transform, trans) layer = superlayer } return trans } func removeAllHeroAnimations() { guard let keys = animationKeys() else { return } for animationKey in keys where animationKey.hasPrefix("hero.") { removeAnimation(forKey: animationKey) } } } #endif ================================================ FILE: Sources/Extensions/CAMediaTimingFunction+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(QuartzCore) import QuartzCore public extension CAMediaTimingFunction { // default static let linear = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) static let easeIn = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn) static let easeOut = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) static let easeInOut = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) // material static let standard = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 0.2, 1.0) static let deceleration = CAMediaTimingFunction(controlPoints: 0.0, 0.0, 0.2, 1) static let acceleration = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 1, 1) static let sharp = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 0.6, 1) // easing.net static let easeOutBack = CAMediaTimingFunction(controlPoints: 0.175, 0.885, 0.32, 1.275) static func from(name: String) -> CAMediaTimingFunction? { switch name { case "linear": return .linear case "easeIn": return .easeIn case "easeOut": return .easeOut case "easeInOut": return .easeInOut case "standard": return .standard case "deceleration": return .deceleration case "acceleration": return .acceleration case "sharp": return .sharp default: return nil } } } #endif ================================================ FILE: Sources/Extensions/CG+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import QuartzCore let π = CGFloat.pi internal struct KeySet { var dict: [Key: Set] = [:] internal subscript(key: Key) -> Set { mutating get { if dict[key] == nil { dict[key] = Set() } return dict[key]! } set { dict[key] = newValue } } } internal extension CGSize { var center: CGPoint { return CGPoint(x: width / 2, y: height / 2) } var point: CGPoint { return CGPoint(x: width, y: height) } func transform(_ t: CGAffineTransform) -> CGSize { return self.applying(t) } func transform(_ t: CATransform3D) -> CGSize { return self.applying(CATransform3DGetAffineTransform(t)) } } internal extension CGRect { var center: CGPoint { return CGPoint(x: origin.x + width / 2, y: origin.y + height / 2) } var bounds: CGRect { return CGRect(origin: CGPoint.zero, size: size) } init(center: CGPoint, size: CGSize) { self.init(x: center.x - size.width / 2, y: center.y - size.height / 2, width: size.width, height: size.height) } } internal extension CGFloat { func clamp(_ a: CGFloat, _ b: CGFloat) -> CGFloat { return self < a ? a : (self > b ? b : self) } } internal extension TimeInterval { func clamp(_ a: TimeInterval, _ b: TimeInterval) -> TimeInterval { return self < a ? a : (self > b ? b : self) } } internal extension CGPoint { func translate(_ dx: CGFloat, dy: CGFloat) -> CGPoint { return CGPoint(x: self.x + dx, y: self.y + dy) } func transform(_ t: CGAffineTransform) -> CGPoint { return self.applying(t) } func transform(_ t: CATransform3D) -> CGPoint { return self.applying(CATransform3DGetAffineTransform(t)) } func distance(_ b: CGPoint) -> CGFloat { return sqrt(pow(self.x - b.x, 2) + pow(self.y - b.y, 2)) } static func + (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x + right.x, y: left.y + right.y) } static func - (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x - right.x, y: left.y - right.y) } static func / (left: CGPoint, right: CGFloat) -> CGPoint { return CGPoint(x: left.x / right, y: left.y / right) } static func / (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x / right.x, y: left.y / right.y) } static func * (left: CGPoint, right: CGFloat) -> CGPoint { return CGPoint(x: left.x * right, y: left.y * right) } static func * (left: CGPoint, right: CGSize) -> CGPoint { return CGPoint(x: left.x * right.width, y: left.y * right.height) } static func * (left: CGFloat, right: CGPoint) -> CGPoint { return right * left } static func * (left: CGPoint, right: CGPoint) -> CGPoint { return CGPoint(x: left.x * right.x, y: left.y * right.y) } static prefix func - (point: CGPoint) -> CGPoint { return .zero - point } static func abs(_ p: CGPoint) -> CGPoint { return CGPoint(x: Swift.abs(p.x), y: Swift.abs(p.y)) } } internal extension CGSize { static func * (left: CGSize, right: CGFloat) -> CGSize { return CGSize(width: left.width * right, height: left.height * right) } static func * (left: CGSize, right: CGSize) -> CGSize { return CGSize(width: left.width * right.width, height: left.height * right.height) } static func / (left: CGSize, right: CGSize) -> CGSize { return CGSize(width: left.width / right.width, height: left.height / right.height) } static func / (left: CGPoint, right: CGSize) -> CGPoint { return CGPoint(x: left.x / right.width, y: left.y / right.height) } } extension CATransform3D: Equatable { public static func == (lhs: CATransform3D, rhs: CATransform3D) -> Bool { var lhs = lhs var rhs = rhs return memcmp(&lhs, &rhs, MemoryLayout.size) == 0 } } ================================================ FILE: Sources/Extensions/DispatchQueue+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation func delay(_ time: Double, execute: @escaping () -> Void) { if time > 0 { DispatchQueue.main.asyncAfter(deadline: .now() + time, execute: execute) } else { DispatchQueue.main.async(execute: execute) } } ================================================ FILE: Sources/Extensions/Locale+Hero.swift ================================================ // // Locale+Hero.swift // Hero // // Created by Joseph Mattiello on 4/25/20. // Copyright © 2020 Luke Zhao. All rights reserved. // import Foundation internal extension Locale { static var isDeviceLanguageRightToLeft: Bool { let currentLocale: Locale = Locale.current guard let code: String = currentLocale.languageCode else { return false } let direction: Locale.LanguageDirection = Locale.characterDirection(forLanguage: code) return (direction == .rightToLeft) } static var isDeviceLanguageLeftToRight: Bool { return !isDeviceLanguageRightToLeft } } ================================================ FILE: Sources/Extensions/UIColor+HexString.swift ================================================ // // UIColor+HexString.swift // Hero // // Created by Joseph Mattiello on 10/21/19. // Copyright © 2019 Luke Zhao. All rights reserved. // #if canImport(UIKit) import UIKit.UIColor extension UIColor { convenience init?(hexString hex: String) { var cString: String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() if cString.hasPrefix("#") { cString.remove(at: cString.startIndex) } guard cString.count == 6 else { return nil } var rgbValue: UInt64 = 0 Scanner(string: cString).scanHexInt64(&rgbValue) self.init( red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, blue: CGFloat(rgbValue & 0x0000FF) / 255.0, alpha: CGFloat(1.0) ) } } #endif ================================================ FILE: Sources/Extensions/UIKit+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit private let parameterRegex = "(?:\\-?\\d+(\\.?\\d+)?)|\\w+" private let modifiersRegex = "(\\w+)(?:\\(([^\\)]*)\\))?" internal extension NSCoding where Self: NSObject { func copyWithArchiver() -> Any? { if #available(iOS 11.0, tvOS 11.0, *) { return try? NSKeyedUnarchiver.unarchivedObject(ofClass: type(of: self), from: NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)) } else { return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! } } } internal extension UIImage { class func imageWithView(view: UIView) -> UIImage { UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0) view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return img! } } internal extension UIColor { var components:(r:CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) { var r: CGFloat = 0 var g: CGFloat = 0 var b: CGFloat = 0 var a: CGFloat = 0 getRed(&r, green: &g, blue: &b, alpha: &a) return (r, g, b, a) } var alphaComponent: CGFloat { return components.a } } #endif ================================================ FILE: Sources/Extensions/UIView+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit class SnapshotWrapperView: UIView { let contentView: UIView init(contentView: UIView) { self.contentView = contentView super.init(frame: contentView.frame) addSubview(contentView) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() contentView.bounds.size = bounds.size contentView.center = bounds.center } } extension UIView: HeroCompatible { } public extension HeroExtension where Base: UIView { /** **ID** 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. */ var id: String? { get { return objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.heroID) as? String } set { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroID, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /** **isEnabled** allows to specify whether a view and its subviews should be consider for animations. If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true */ var isEnabled: Bool { get { return objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.heroEnabled) as? Bool ?? true } set { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroEnabled, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /** **isEnabledForSubviews** allows to specify whether a view's subviews should be consider for animations. If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true */ var isEnabledForSubviews: Bool { get { return objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.heroEnabledForSubviews) as? Bool ?? true } set { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroEnabledForSubviews, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /** Use **modifiers** to specify animations alongside the main transition. Checkout `HeroModifier.swift` for available modifiers. */ var modifiers: [HeroModifier]? { get { return objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.heroModifiers) as? [HeroModifier] } set { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroModifiers, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /** **modifierString** provides another way to set **modifiers**. It can be assigned through storyboard. */ var modifierString: String? { get { fatalError("Reverse lookup is not supported") } set { modifiers = newValue?.parse() } } /// Used for .overFullScreen presentation internal var storedAlpha: CGFloat? { get { if let doubleValue = (objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.heroStoredAlpha) as? NSNumber)?.doubleValue { return CGFloat(doubleValue) } return nil } set { if let newValue = newValue { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroStoredAlpha, NSNumber(value: newValue.native), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } else { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroStoredAlpha, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } } } public extension UIView { fileprivate struct AssociatedKeys { static var heroID = "heroID" static var heroModifiers = "heroModifers" static var heroStoredAlpha = "heroStoredAlpha" static var heroEnabled = "heroEnabled" static var heroEnabledForSubviews = "heroEnabledForSubviews" } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, renamed: "hero.id") @IBInspectable var heroID: String? { get { return hero.id } set { hero.id = newValue } } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, renamed: "hero.isEnabled") @IBInspectable var isHeroEnabled: Bool { get { return hero.isEnabled } set { hero.isEnabled = newValue } } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, renamed: "hero.isEnabledForSubviews") @IBInspectable var isHeroEnabledForSubviews: Bool { get { return hero.isEnabledForSubviews } set { hero.isEnabledForSubviews = newValue } } @available(*, renamed: "hero.modifiers") var heroModifiers: [HeroModifier]? { get { return hero.modifiers } set { hero.modifiers = newValue } } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, renamed: "hero.modifierString") @IBInspectable var heroModifierString: String? { get { fatalError("Reverse lookup is not supported") } set { hero.modifiers = newValue?.parse() } } internal func slowSnapshotView() -> UIView { UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0) guard let currentContext = UIGraphicsGetCurrentContext() else { UIGraphicsEndImageContext() return UIView() } layer.render(in: currentContext) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() let imageView = UIImageView(image: image) imageView.frame = bounds return SnapshotWrapperView(contentView: imageView) } internal func snapshotView() -> UIView? { let snapshot = snapshotView(afterScreenUpdates: true) if #available(iOS 11.0, *), let oldSnapshot = snapshot { // in iOS 11, the snapshot taken by snapshotView(afterScreenUpdates) won't contain a container view return SnapshotWrapperView(contentView: oldSnapshot) } else { return snapshot } } internal var flattenedViewHierarchy: [UIView] { guard hero.isEnabled else { return [] } if #available(iOS 9.0, *), isHidden && (superview is UICollectionView || superview is UIStackView || self is UITableViewCell) { return [] } else if isHidden && (superview is UICollectionView || self is UITableViewCell) { return [] } else if hero.isEnabledForSubviews { return [self] + subviews.flatMap { $0.flattenedViewHierarchy } } else { return [self] } } @available(*, renamed: "hero.storedAplha") internal var heroStoredAlpha: CGFloat? { get { return hero.storedAlpha } set { hero.storedAlpha = newValue } } } #endif ================================================ FILE: Sources/Extensions/UIViewController+Hero.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit internal class HeroViewControllerConfig: NSObject { var modalAnimation: HeroDefaultAnimationType = .auto var navigationAnimation: HeroDefaultAnimationType = .auto var tabBarAnimation: HeroDefaultAnimationType = .auto var storedSnapshot: UIView? weak var previousNavigationDelegate: UINavigationControllerDelegate? weak var previousTabBarDelegate: UITabBarControllerDelegate? } extension UIViewController: HeroCompatible { } public extension HeroExtension where Base: UIViewController { internal var config: HeroViewControllerConfig { get { if let config = objc_getAssociatedObject(base, &type(of: base).AssociatedKeys.heroConfig) as? HeroViewControllerConfig { return config } let config = HeroViewControllerConfig() self.config = config return config } set { objc_setAssociatedObject(base, &type(of: base).AssociatedKeys.heroConfig, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /// used for .overFullScreen presentation internal var storedSnapshot: UIView? { get { return config.storedSnapshot } set { config.storedSnapshot = newValue } } /// default hero animation type for presenting & dismissing modally var modalAnimationType: HeroDefaultAnimationType { get { return config.modalAnimation } set { config.modalAnimation = newValue } } // TODO: can be moved to internal later (will still be accessible via IB) var modalAnimationTypeString: String? { get { return config.modalAnimation.label } set { config.modalAnimation = newValue?.parseOne() ?? .auto } } // TODO: can be moved to internal later (will still be accessible via IB) var isEnabled: Bool { get { return base.transitioningDelegate is HeroTransition } set { guard newValue != isEnabled else { return } if newValue { base.transitioningDelegate = Hero.shared if let navi = base as? UINavigationController { base.previousNavigationDelegate = navi.delegate navi.delegate = Hero.shared } if let tab = base as? UITabBarController { base.previousTabBarDelegate = tab.delegate tab.delegate = Hero.shared } } else { base.transitioningDelegate = nil if let navi = base as? UINavigationController, navi.delegate is HeroTransition { navi.delegate = base.previousNavigationDelegate } if let tab = base as? UITabBarController, tab.delegate is HeroTransition { tab.delegate = base.previousTabBarDelegate } } } } } public extension UIViewController { fileprivate struct AssociatedKeys { static var heroConfig = "heroConfig" } @available(*, renamed: "hero.config") internal var heroConfig: HeroViewControllerConfig { get { return hero.config } set { hero.config = newValue } } internal var previousNavigationDelegate: UINavigationControllerDelegate? { get { return hero.config.previousNavigationDelegate } set { hero.config.previousNavigationDelegate = newValue } } internal var previousTabBarDelegate: UITabBarControllerDelegate? { get { return hero.config.previousTabBarDelegate } set { hero.config.previousTabBarDelegate = newValue } } @available(*, renamed: "hero.storedSnapshot") internal var heroStoredSnapshot: UIView? { get { return hero.config.storedSnapshot } set { hero.config.storedSnapshot = newValue } } @available(*, renamed: "hero.modalAnimationType") var heroModalAnimationType: HeroDefaultAnimationType { get { return hero.modalAnimationType } set { hero.modalAnimationType = newValue } } @available(*, renamed: "hero.modalAnimationTypeString") @IBInspectable var heroModalAnimationTypeString: String? { get { return hero.modalAnimationTypeString } set { hero.modalAnimationTypeString = newValue } } @available(*, renamed: "hero.isEnabled") @IBInspectable var isHeroEnabled: Bool { get { return hero.isEnabled } set { hero.isEnabled = newValue } } } public extension HeroExtension where Base: UINavigationController { /// default hero animation type for push and pop within the navigation controller var navigationAnimationType: HeroDefaultAnimationType { get { return config.navigationAnimation } set { config.navigationAnimation = newValue } } var navigationAnimationTypeString: String? { get { return config.navigationAnimation.label } set { config.navigationAnimation = newValue?.parseOne() ?? .auto } } } extension UINavigationController { @available(*, renamed: "hero.navigationAnimationType") public var heroNavigationAnimationType: HeroDefaultAnimationType { get { return hero.navigationAnimationType } set { hero.navigationAnimationType = newValue } } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, renamed: "hero.navigationAnimationTypeString") @IBInspectable public var heroNavigationAnimationTypeString: String? { get { return hero.navigationAnimationTypeString } set { hero.navigationAnimationTypeString = newValue } } /// This function call the standard setViewControllers() but it also add a completion callback. func setViewControllers(viewControllers: [UIViewController], animated: Bool, completion: (() -> Void)?) { setViewControllers(viewControllers, animated: animated) guard animated, let coordinator = transitionCoordinator else { DispatchQueue.main.async { completion?() } return } coordinator.animate(alongsideTransition: nil) { _ in completion?() } } } public extension HeroExtension where Base: UITabBarController { /// default hero animation type for switching tabs within the tab bar controller var tabBarAnimationType: HeroDefaultAnimationType { get { return config.tabBarAnimation } set { config.tabBarAnimation = newValue } } var tabBarAnimationTypeString: String? { get { return config.tabBarAnimation.label } set { config.tabBarAnimation = newValue?.parseOne() ?? .auto } } } public extension UITabBarController { @available(*, renamed: "hero.tabBarAnimationType") var heroTabBarAnimationType: HeroDefaultAnimationType { get { return hero.tabBarAnimationType } set { hero.tabBarAnimationType = newValue } } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, renamed: "hero.tabBarAnimationTypeString") @IBInspectable var heroTabBarAnimationTypeString: String? { get { return hero.tabBarAnimationTypeString } set { hero.tabBarAnimationTypeString = newValue } } } public extension HeroExtension where Base: UIViewController { /** Dismiss the current view controller with animation. Will perform a navigationController.popViewController if the current view controller is contained inside a navigationController */ func dismissViewController(completion: (() -> Void)? = nil) { if let navigationController = base.navigationController, navigationController.viewControllers.first != base { navigationController.popViewController(animated: true) } else { base.dismiss(animated: true, completion: completion) } } /** Unwind to the root view controller using Hero */ func unwindToRootViewController() { unwindToViewController { $0.presentingViewController == nil } } /** Unwind to a specific view controller using Hero */ func unwindToViewController(_ toViewController: UIViewController) { unwindToViewController { $0 == toViewController } } func unwindToViewController(withSelector: Selector) { unwindToViewController { $0.responds(to: withSelector) } } /** Unwind to a view controller with given class using Hero */ func unwindToViewController(withClass: AnyClass) { unwindToViewController { $0.isKind(of: withClass) } } /** Unwind to a view controller that the matchBlock returns true on. */ func unwindToViewController(withMatchBlock: (UIViewController) -> Bool) { var target: UIViewController? var current: UIViewController? = base while target == nil && current != nil { if let childViewControllers = (current as? UINavigationController)?.children ?? current!.navigationController?.children { for vc in childViewControllers.reversed() { if vc != base, withMatchBlock(vc) { target = vc break } } } if target == nil { current = current!.presentingViewController if let vc = current, withMatchBlock(vc) == true { target = vc } } } if let target = target { if target.presentedViewController != nil { _ = target.navigationController?.popToViewController(target, animated: false) let fromVC = base.navigationController ?? base let toVC = target.navigationController ?? target if target.presentedViewController != fromVC { // UIKit's UIViewController.dismiss will jump to target.presentedViewController then perform the dismiss. // We overcome this behavior by inserting a snapshot into target.presentedViewController // And also force Hero to use the current VC as the fromViewController Hero.shared.fromViewController = fromVC let snapshotView = fromVC.view.snapshotView(afterScreenUpdates: true)! let targetSuperview = toVC.presentedViewController!.view! if let visualEffectView = targetSuperview as? UIVisualEffectView { visualEffectView.contentView.addSubview(snapshotView) } else { targetSuperview.addSubview(snapshotView) } } toVC.dismiss(animated: true, completion: nil) } else { _ = target.navigationController?.popToViewController(target, animated: true) } } else { // unwind target not found } } /** Replace the current view controller with another VC on the navigation/modal/root view of UIWindow stack. */ func replaceViewController(with next: UIViewController, completion: (() -> Void)? = nil) { let hero = next.transitioningDelegate as? HeroTransition ?? Hero.shared if hero.isTransitioning { print("hero.replaceViewController cancelled because Hero was doing a transition. Use Hero.shared.cancel(animated:false) or Hero.shared.end(animated:false) to stop the transition first before calling hero.replaceViewController.") return } if let navigationController = base.navigationController { var vcs = navigationController.children if !vcs.isEmpty { vcs.removeLast() vcs.append(next) } if navigationController.hero.isEnabled { hero.forceNotInteractive = true } navigationController.setViewControllers(viewControllers: vcs, animated: true, completion: completion) } else if let container = base.view.superview, let parentVC = base.presentingViewController { hero.transition(from: base, to: next, in: container) { [weak base] finished in guard let base = base, finished else { return } next.view.window?.addSubview(next.view) base.dismiss(animated: false) { parentVC.present(next, animated: false, completion: completion) } } } else if let baseWindow = base.view.window, baseWindow.rootViewController == base { hero.transition(from: base, to: next, in: baseWindow) { [weak base] finished in guard base != nil, finished else { return } baseWindow.rootViewController = next } } } } extension UIViewController { @available(*, deprecated, renamed: "hero.dismissViewController()") @IBAction public func ht_dismiss(_ sender: UIView) { hero.dismissViewController() } @available(*, deprecated, renamed: "hero.replaceViewController(with:)") public func heroReplaceViewController(with next: UIViewController) { hero.replaceViewController(with: next) } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, deprecated, renamed: "hero.dismissViewController()") @IBAction public func hero_dismissViewController() { hero.dismissViewController() } // TODO: can be moved to internal later (will still be accessible via IB) @available(*, deprecated, renamed: "hero.unwindToRootViewController()") @IBAction public func hero_unwindToRootViewController() { hero.unwindToRootViewController() } @available(*, deprecated, renamed: "hero.unwindToViewController(_:)") public func hero_unwindToViewController(_ toViewController: UIViewController) { hero.unwindToViewController(toViewController) } @available(*, deprecated, renamed: "hero.unwindToViewController(withSelector:)") public func hero_unwindToViewController(withSelector: Selector) { hero.unwindToViewController(withSelector: withSelector) } @available(*, deprecated, renamed: "hero_unwindToViewController(withClass:)") public func hero_unwindToViewController(withClass: AnyClass) { hero.unwindToViewController(withClass: withClass) } @available(*, deprecated, renamed: "hero.unwindToViewController(withMatchBlock:)") public func hero_unwindToViewController(withMatchBlock: (UIViewController) -> Bool) { hero.unwindToViewController(withMatchBlock: withMatchBlock) } @available(*, deprecated, renamed: "hero.replaceViewController(with:)") public func hero_replaceViewController(with next: UIViewController) { hero.replaceViewController(with: next) } } #endif ================================================ FILE: Sources/Hero.h ================================================ // // Hero.h // Hero // // Created by YiLun Zhao on 2017-01-03. // Copyright © 2017 Luke Zhao. All rights reserved. // #import //! Project version number for Hero. FOUNDATION_EXPORT double HeroVersionNumber; //! Project version string for Hero. FOUNDATION_EXPORT const unsigned char HeroVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import ================================================ FILE: Sources/HeroCompatible.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation public protocol HeroCompatible { associatedtype CompatibleType var hero: HeroExtension { get set } } public extension HeroCompatible { var hero: HeroExtension { get { return HeroExtension(self) } // swiftlint:disable unused_setter_value set { } } } public class HeroExtension { public let base: Base init(_ base: Base) { self.base = base } } ================================================ FILE: Sources/HeroContext.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit public class HeroContext { internal var heroIDToSourceView = [String: UIView]() internal var heroIDToDestinationView = [String: UIView]() internal var snapshotViews = [UIView: UIView]() internal var viewAlphas = [UIView: CGFloat]() internal var targetStates = [UIView: HeroTargetState]() internal var superviewToNoSnapshotSubviewMap: [UIView: [(Int, UIView)]] = [:] internal var insertToViewFirst = false internal var defaultCoordinateSpace: HeroCoordinateSpace = .local internal init(container: UIView) { self.container = container } internal func set(fromViews: [UIView], toViews: [UIView]) { self.fromViews = fromViews self.toViews = toViews process(views: fromViews, idMap: &heroIDToSourceView) process(views: toViews, idMap: &heroIDToDestinationView) } internal func process(views: [UIView], idMap: inout [String: UIView]) { for view in views { view.layer.removeAllHeroAnimations() let targetState: HeroTargetState? if let modifiers = view.hero.modifiers { targetState = HeroTargetState(modifiers: modifiers) } else { targetState = nil } if targetState?.forceAnimate == true || container.convert(view.bounds, from: view).intersects(container.bounds) { if let heroID = view.hero.id { idMap[heroID] = view } targetStates[view] = targetState } } } /** The container holding all of the animating views */ public let container: UIView /** A flattened list of all views from source ViewController */ public var fromViews: [UIView] = [] /** A flattened list of all views from destination ViewController */ public var toViews: [UIView] = [] } // public extension HeroContext { /** - Returns: a source view matching the heroID, nil if not found */ public func sourceView(for heroID: String) -> UIView? { return heroIDToSourceView[heroID] } /** - Returns: a destination view matching the heroID, nil if not found */ public func destinationView(for heroID: String) -> UIView? { return heroIDToDestinationView[heroID] } /** - Returns: a view with the same heroID, but on different view controller, nil if not found */ public func pairedView(for view: UIView) -> UIView? { if let id = view.hero.id { if sourceView(for: id) == view { return destinationView(for: id) } else if destinationView(for: id) == view { return sourceView(for: id) } } return nil } /** - Returns: a snapshot view for animation */ public func snapshotView(for view: UIView) -> UIView { if let snapshot = snapshotViews[view] { return snapshot } var containerView = container let coordinateSpace = targetStates[view]?.coordinateSpace ?? defaultCoordinateSpace switch coordinateSpace { case .local: containerView = view while containerView != container, snapshotViews[containerView] == nil, let superview = containerView.superview { containerView = superview } if let snapshot = snapshotViews[containerView] { containerView = snapshot } if let visualEffectView = containerView as? UIVisualEffectView { containerView = visualEffectView.contentView } case .global: break } unhide(view: view) let oldCornerRadius = view.layer.cornerRadius let oldAlpha = view.alpha let oldShadowRadius = view.layer.shadowRadius let oldShadowOffset = view.layer.shadowOffset let oldShadowPath = view.layer.shadowPath let oldShadowOpacity = view.layer.shadowOpacity view.layer.cornerRadius = 0 view.alpha = 1 view.layer.shadowRadius = 0.0 view.layer.shadowOffset = .zero view.layer.shadowPath = nil view.layer.shadowOpacity = 0.0 let snapshot: UIView let snapshotType: HeroSnapshotType = self[view]?.snapshotType ?? .optimized switch snapshotType { case .normal: snapshot = view.snapshotView() ?? UIView() case .layerRender: snapshot = view.slowSnapshotView() case .noSnapshot: if let superview = view.superview, superview != container { if superviewToNoSnapshotSubviewMap[superview] == nil { superviewToNoSnapshotSubviewMap[superview] = [] } if let index = superview.subviews.firstIndex(of: view) { superviewToNoSnapshotSubviewMap[superview]!.append((index, view)) } } snapshot = view case .optimized: #if os(tvOS) snapshot = view.snapshotView(afterScreenUpdates: true)! #else if let customSnapshotView = view as? HeroCustomSnapshotView, let snapshotView = customSnapshotView.heroSnapshot { snapshot = snapshotView } else if #available(iOS 9.0, *), let stackView = view as? UIStackView { snapshot = stackView.slowSnapshotView() } else if let imageView = view as? UIImageView, view.subviews.filter({!$0.isHidden}).isEmpty { let contentView = UIImageView(image: imageView.image) contentView.frame = imageView.bounds contentView.contentMode = imageView.contentMode contentView.tintColor = imageView.tintColor contentView.backgroundColor = imageView.backgroundColor contentView.layer.magnificationFilter = imageView.layer.magnificationFilter contentView.layer.minificationFilter = imageView.layer.minificationFilter contentView.layer.minificationFilterBias = imageView.layer.minificationFilterBias let snapShotView = UIView() snapShotView.addSubview(contentView) snapshot = snapShotView } else if let barView = view as? UINavigationBar, barView.isTranslucent { let newBarView = UINavigationBar(frame: barView.frame) newBarView.barStyle = barView.barStyle newBarView.tintColor = barView.tintColor newBarView.barTintColor = barView.barTintColor newBarView.clipsToBounds = false // take a snapshot without the background barView.layer.sublayers![0].opacity = 0 let realSnapshot = barView.snapshotView(afterScreenUpdates: true)! barView.layer.sublayers![0].opacity = 1 newBarView.addSubview(realSnapshot) snapshot = newBarView } else if let effectView = view as? UIVisualEffectView { snapshot = UIVisualEffectView(effect: effectView.effect) snapshot.frame = effectView.bounds } else { snapshot = view.snapshotView() ?? UIView() } #endif } #if os(tvOS) if let imageView = view as? UIImageView, imageView.adjustsImageWhenAncestorFocused { snapshot.frame = imageView.focusedFrameGuide.layoutFrame } #endif if #available(iOSApplicationExtension 11.0, tvOSApplicationExtension 11.0, iOS 11, tvOS 11, *) { // capture a snapshot without alpha, cornerRadius, or shadows let oldMaskedCorners: CACornerMask = { return view.layer.maskedCorners }() view.layer.maskedCorners = oldMaskedCorners } view.layer.cornerRadius = oldCornerRadius view.alpha = oldAlpha view.layer.shadowRadius = oldShadowRadius view.layer.shadowOffset = oldShadowOffset view.layer.shadowPath = oldShadowPath view.layer.shadowOpacity = oldShadowOpacity snapshot.layer.anchorPoint = view.layer.anchorPoint if let superview = view.superview { snapshot.layer.position = containerView.convert(view.layer.position, from: superview) } snapshot.layer.transform = containerView.layer.flatTransformTo(layer: view.layer) snapshot.layer.bounds = view.layer.bounds snapshot.hero.id = view.hero.id if snapshotType != .noSnapshot { if !(view is UINavigationBar), let contentView = snapshot.subviews.get(0) { // the Snapshot's contentView must have hold the cornerRadius value, // since the snapshot might not have maskToBounds set if #available(iOS 11, tvOS 11, *) { contentView.layer.maskedCorners = view.layer.maskedCorners } contentView.layer.cornerRadius = view.layer.cornerRadius contentView.layer.masksToBounds = true } if #available(iOS 11, tvOS 11, *) { snapshot.layer.maskedCorners = view.layer.maskedCorners } snapshot.layer.cornerRadius = view.layer.cornerRadius snapshot.layer.allowsGroupOpacity = false snapshot.layer.zPosition = view.layer.zPosition snapshot.layer.opacity = view.layer.opacity snapshot.layer.isOpaque = view.layer.isOpaque snapshot.layer.anchorPoint = view.layer.anchorPoint snapshot.layer.masksToBounds = view.layer.masksToBounds snapshot.layer.borderColor = view.layer.borderColor snapshot.layer.borderWidth = view.layer.borderWidth snapshot.layer.contentsRect = view.layer.contentsRect snapshot.layer.contentsScale = view.layer.contentsScale if self[view]?.displayShadow ?? true { snapshot.layer.shadowRadius = view.layer.shadowRadius snapshot.layer.shadowOpacity = view.layer.shadowOpacity snapshot.layer.shadowColor = view.layer.shadowColor snapshot.layer.shadowOffset = view.layer.shadowOffset snapshot.layer.shadowPath = view.layer.shadowPath } hide(view: view) } if let pairedView = pairedView(for: view), let pairedSnapshot = snapshotViews[pairedView], let siblingViews = pairedView.superview?.subviews, let index = siblingViews.firstIndex(of: pairedView) { let nextSiblings = siblingViews[index+1.. HeroTargetState? { get { return targetStates[view] } set { targetStates[view] = newValue } } public func clean() { for (superview, subviews) in superviewToNoSnapshotSubviewMap { for (index, view) in subviews.reversed() { superview.insertSubview(view, at: index) } } } } // internal extension HeroContext { public func hide(view: UIView) { if viewAlphas[view] == nil { if view is UIVisualEffectView { view.isHidden = true viewAlphas[view] = 1 } else { viewAlphas[view] = view.alpha view.alpha = 0 } } } public func unhide(view: UIView) { if let oldAlpha = viewAlphas[view] { if view is UIVisualEffectView { view.isHidden = false } else { view.alpha = oldAlpha } viewAlphas[view] = nil } } internal func unhideAll() { for view in viewAlphas.keys { unhide(view: view) } viewAlphas.removeAll() } internal func unhide(rootView: UIView) { unhide(view: rootView) for subview in rootView.subviews { unhide(rootView: subview) } } internal func removeAllSnapshots() { for (view, snapshot) in snapshotViews { if view != snapshot { snapshot.removeFromSuperview() } else { view.layer.removeAllHeroAnimations() } } } internal func removeSnapshots(rootView: UIView) { if let snapshot = snapshotViews[rootView] { if rootView != snapshot { snapshot.removeFromSuperview() } else { rootView.layer.removeAllHeroAnimations() } } for subview in rootView.subviews { removeSnapshots(rootView: subview) } } internal func snapshots(rootView: UIView) -> [UIView] { var snapshots = [UIView]() for v in rootView.flattenedViewHierarchy { if let snapshot = snapshotViews[v] { snapshots.append(snapshot) } } return snapshots } internal func loadViewAlpha(rootView: UIView) { if let storedAlpha = rootView.hero.storedAlpha { rootView.alpha = storedAlpha rootView.hero.storedAlpha = nil } for subview in rootView.subviews { loadViewAlpha(rootView: subview) } } internal func storeViewAlpha(rootView: UIView) { rootView.hero.storedAlpha = viewAlphas[rootView] for subview in rootView.subviews { storeViewAlpha(rootView: subview) } } } /// Allows a view to create their own custom snapshot when using **Optimized** snapshot public protocol HeroCustomSnapshotView { var heroSnapshot: UIView? { get } } #endif ================================================ FILE: Sources/HeroModifier+Advanced.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #if canImport(UIKit) // advance modifiers extension HeroModifier { /** Apply modifiers directly to the view at the start of the transition. The modifiers supplied here won't be animated. For source views, modifiers are set directly at the beginning of the animation. For destination views, they replace the target state (final appearance). */ public static func beginWith(_ modifiers: [HeroModifier]) -> HeroModifier { return HeroModifier { targetState in if targetState.beginState == nil { targetState.beginState = [] } targetState.beginState!.append(contentsOf: modifiers) } } public static func beginWith(modifiers: [HeroModifier]) -> HeroModifier { return .beginWith(modifiers) } public static func beginWith(_ modifiers: HeroModifier...) -> HeroModifier { return .beginWith(modifiers) } /** Use global coordinate space. When using global coordinate space. The view become a independent view that is not a subview of any view. It won't move when its parent view moves, and won't be affected by parent view's attributes. When a view is matched, this is automatically enabled. The `source` modifier will also enable this. Global coordinate space is default for all views prior to version 0.1.3 */ public static var useGlobalCoordinateSpace: HeroModifier = HeroModifier { targetState in targetState.coordinateSpace = .global } /** ignore all heroModifiers attributes for a view's direct subviews. */ public static var ignoreSubviewModifiers: HeroModifier = .ignoreSubviewModifiers() /** ignore all heroModifiers attributes for a view's subviews. - Parameters: - recursive: if false, will only ignore direct subviews' modifiers. default false. */ public static func ignoreSubviewModifiers(recursive: Bool = false) -> HeroModifier { return HeroModifier { targetState in targetState.ignoreSubviewModifiers = recursive } } /** Will create snapshot optimized for different view type. 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. This modifier actually does nothing by itself since .useOptimizedSnapshot is the default. */ public static var useOptimizedSnapshot: HeroModifier = HeroModifier { targetState in targetState.snapshotType = .optimized } /** Create snapshot using snapshotView(afterScreenUpdates:). */ public static var useNormalSnapshot: HeroModifier = HeroModifier { targetState in targetState.snapshotType = .normal } /** Create snapshot using layer.render(in: currentContext). This is slower than .useNormalSnapshot but gives more accurate snapshot for some views (eg. UIStackView). */ public static var useLayerRenderSnapshot: HeroModifier = HeroModifier { targetState in targetState.snapshotType = .layerRender } /** Force Hero to not create any snapshot when animating this view. This will mess up the view hierarchy, therefore, view controllers have to rebuild its view structure after the transition finishes. */ public static var useNoSnapshot: HeroModifier = HeroModifier { targetState in targetState.snapshotType = .noSnapshot } /** Force the view to animate. By default, Hero will not animate if the view is outside the screen bounds or if there is no animatable hero modifier, unless this modifier is used. */ public static var forceAnimate = HeroModifier { targetState in targetState.forceAnimate = true } /** 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 performance. */ public static var useScaleBasedSizeChange: HeroModifier = HeroModifier { targetState in targetState.useScaleBasedSizeChange = true } } #endif ================================================ FILE: Sources/HeroModifier+HeroStringConvertible.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit /// used to construct HeroModifier from heroModifierString extension HeroModifier: HeroStringConvertible { public static func from(node: ExprNode) -> HeroModifier? { let name: String = node.name let parameters: [ExprNode] = (node as? CallNode)?.arguments ?? [] switch name { case "fade": return .fade case "opacity": return HeroModifier.opacity(CGFloat(parameters.getFloat(0) ?? 1)) case "position": return .position(CGPoint(x: parameters.getCGFloat(0) ?? 0, y: parameters.getCGFloat(1) ?? 0)) case "size": return .size(CGSize(width: parameters.getCGFloat(0) ?? 0, height: parameters.getCGFloat(1) ?? 0)) case "scale": if parameters.count == 1 { return .scale(parameters.getCGFloat(0) ?? 1) } else { return .scale(x: parameters.getCGFloat(0) ?? 1, y: parameters.getCGFloat(1) ?? 1, z: parameters.getCGFloat(2) ?? 1) } case "rotate": if parameters.count == 1 { return .rotate(parameters.getCGFloat(0) ?? 0) } else { return .rotate(x: parameters.getCGFloat(0) ?? 0, y: parameters.getCGFloat(1) ?? 0, z: parameters.getCGFloat(2) ?? 0) } case "translate": return .translate(x: parameters.getCGFloat(0) ?? 0, y: parameters.getCGFloat(1) ?? 0, z: parameters.getCGFloat(2) ?? 0) #if canImport(UIKit) case "overlay": return .overlay(color: UIColor(red: parameters.getCGFloat(0) ?? 1, green: parameters.getCGFloat(1) ?? 1, blue: parameters.getCGFloat(2) ?? 1, alpha: 1), opacity: parameters.getCGFloat(3) ?? 1) #endif case "duration": if let duration = parameters.getDouble(0) { return .duration(duration) } case "durationMatchLongest": return .durationMatchLongest case "delay": if let delay = parameters.getDouble(0) { return .delay(delay) } case "spring": if #available(iOS 9, *) { return .spring(stiffness: parameters.getCGFloat(0) ?? 250, damping: parameters.getCGFloat(1) ?? 30) } case "timingFunction": if let c1 = parameters.getFloat(0), let c2 = parameters.getFloat(1), let c3 = parameters.getFloat(2), let c4 = parameters.getFloat(3) { return .timingFunction(CAMediaTimingFunction(controlPoints: c1, c2, c3, c4)) } else if let name = parameters.get(0)?.name, let timingFunction = CAMediaTimingFunction.from(name: name) { return .timingFunction(timingFunction) } case "arc": return .arc(intensity: parameters.getCGFloat(0) ?? 1) case "cascade": var cascadeDirection = CascadeDirection.topToBottom if let directionString = parameters.get(1)?.name, let direction = CascadeDirection(directionString) { cascadeDirection = direction } return .cascade(delta: parameters.getDouble(0) ?? 0.02, direction: cascadeDirection, delayMatchedViews: parameters.getBool(2) ?? false) case "source": if let heroID = parameters.get(0)?.name { return .source(heroID: heroID) } case "useGlobalCoordinateSpace": return .useGlobalCoordinateSpace case "ignoreSubviewModifiers": return .ignoreSubviewModifiers(recursive: parameters.getBool(0) ?? false) case "zPosition": if let zPosition = parameters.getCGFloat(0) { return .zPosition(zPosition) } case "useOptimizedSnapshot": return .useOptimizedSnapshot case "useNormalSnapshot": return .useNormalSnapshot case "useLayerRenderSnapshot": return .useLayerRenderSnapshot case "useNoSnapshot": return .useNoSnapshot case "forceAnimate": return .forceAnimate default: break } return nil } } #endif ================================================ FILE: Sources/HeroModifier.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit import CoreGraphics import QuartzCore public final class HeroModifier { internal let apply:(inout HeroTargetState) -> Void public init(applyFunction:@escaping (inout HeroTargetState) -> Void) { apply = applyFunction } } // basic modifiers extension HeroModifier { /** Fade the view during transition */ public static var fade = HeroModifier { targetState in targetState.opacity = 0 } /** Force don't fade view during transition */ public static var forceNonFade = HeroModifier { targetState in targetState.nonFade = true } /** Set the position for the view to animate from/to. - Parameters: - position: position for the view to animate from/to */ public static func position(_ position: CGPoint) -> HeroModifier { return HeroModifier { targetState in targetState.position = position } } /** Set the size for the view to animate from/to. - Parameters: - size: size for the view to animate from/to */ public static func size(_ size: CGSize) -> HeroModifier { return HeroModifier { targetState in targetState.size = size } } } // transform modifiers extension HeroModifier { /** Set the transform for the view to animate from/to. Will override previous perspective, scale, translate, & rotate modifiers - Parameters: - t: the CATransform3D object */ public static func transform(_ t: CATransform3D) -> HeroModifier { return HeroModifier { targetState in targetState.transform = t } } /** Set the perspective on the transform. use in combination with the rotate modifier. - Parameters: - perspective: set the camera distance of the transform */ public static func perspective(_ perspective: CGFloat) -> HeroModifier { return HeroModifier { targetState in var transform = targetState.transform ?? CATransform3DIdentity transform.m34 = 1.0 / -perspective targetState.transform = transform } } /** Scale 3d - Parameters: - x: scale factor on x axis, default 1 - y: scale factor on y axis, default 1 - z: scale factor on z axis, default 1 */ public static func scale(x: CGFloat = 1, y: CGFloat = 1, z: CGFloat = 1) -> HeroModifier { return HeroModifier { targetState in targetState.transform = CATransform3DScale(targetState.transform ?? CATransform3DIdentity, x, y, z) } } /** Scale in x & y axis - Parameters: - xy: scale factor in both x & y axis */ public static func scale(_ xy: CGFloat) -> HeroModifier { return .scale(x: xy, y: xy) } /** Translate 3d - Parameters: - x: translation distance on x axis in display pixel, default 0 - y: translation distance on y axis in display pixel, default 0 - z: translation distance on z axis in display pixel, default 0 */ public static func translate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> HeroModifier { return HeroModifier { targetState in targetState.transform = CATransform3DTranslate(targetState.transform ?? CATransform3DIdentity, x, y, z) } } public static func translate(_ point: CGPoint, z: CGFloat = 0) -> HeroModifier { return translate(x: point.x, y: point.y, z: z) } /** Rotate 3d - Parameters: - x: rotation on x axis in radian, default 0 - y: rotation on y axis in radian, default 0 - z: rotation on z axis in radian, default 0 */ public static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> HeroModifier { return HeroModifier { targetState in targetState.transform = CATransform3DRotate(targetState.transform ?? CATransform3DIdentity, x, 1, 0, 0) targetState.transform = CATransform3DRotate(targetState.transform!, y, 0, 1, 0) targetState.transform = CATransform3DRotate(targetState.transform!, z, 0, 0, 1) } } public static func rotate(_ point: CGPoint, z: CGFloat = 0) -> HeroModifier { return rotate(x: point.x, y: point.y, z: z) } /** Rotate 2d - Parameters: - z: rotation in radian */ public static func rotate(_ z: CGFloat) -> HeroModifier { return .rotate(z: z) } } // MARK: UIKit extension HeroModifier { /** Set the backgroundColor for the view to animate from/to. - Parameters: - backgroundColor: backgroundColor for the view to animate from/to */ public static func backgroundColor(_ backgroundColor: UIColor) -> HeroModifier { return HeroModifier { targetState in targetState.backgroundColor = backgroundColor.cgColor } } /** Set the borderColor for the view to animate from/to. - Parameters: - borderColor: borderColor for the view to animate from/to */ public static func borderColor(_ borderColor: UIColor) -> HeroModifier { return HeroModifier { targetState in targetState.borderColor = borderColor.cgColor } } /** Set the shadowColor for the view to animate from/to. - Parameters: - shadowColor: shadowColor for the view to animate from/to */ public static func shadowColor(_ shadowColor: UIColor) -> HeroModifier { return HeroModifier { targetState in targetState.shadowColor = shadowColor.cgColor } } /** Create an overlay on the animating view. - Parameters: - color: color of the overlay - opacity: opacity of the overlay */ public static func overlay(color: UIColor, opacity: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.overlay = (color.cgColor, opacity) } } } extension HeroModifier { /** Set the opacity for the view to animate from/to. - Parameters: - opacity: opacity for the view to animate from/to */ public static func opacity(_ opacity: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.opacity = Float(opacity) } } /** Set the cornerRadius for the view to animate from/to. - Parameters: - cornerRadius: cornerRadius for the view to animate from/to */ public static func cornerRadius(_ cornerRadius: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.cornerRadius = cornerRadius } } /** Set the zPosition for the view to animate from/to. - Parameters: - zPosition: zPosition for the view to animate from/to */ public static func zPosition(_ zPosition: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.zPosition = zPosition } } /** Set the contentsRect for the view to animate from/to. - Parameters: - contentsRect: contentsRect for the view to animate from/to */ public static func contentsRect(_ contentsRect: CGRect) -> HeroModifier { return HeroModifier { targetState in targetState.contentsRect = contentsRect } } /** Set the contentsScale for the view to animate from/to. - Parameters: - contentsScale: contentsScale for the view to animate from/to */ public static func contentsScale(_ contentsScale: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.contentsScale = contentsScale } } /** Set the borderWidth for the view to animate from/to. - Parameters: - borderWidth: borderWidth for the view to animate from/to */ public static func borderWidth(_ borderWidth: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.borderWidth = borderWidth } } /** Set the shadowOpacity for the view to animate from/to. - Parameters: - shadowOpacity: shadowOpacity for the view to animate from/to */ public static func shadowOpacity(_ shadowOpacity: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.shadowOpacity = Float(shadowOpacity) } } /** Set the shadowOffset for the view to animate from/to. - Parameters: - shadowOffset: shadowOffset for the view to animate from/to */ public static func shadowOffset(_ shadowOffset: CGSize) -> HeroModifier { return HeroModifier { targetState in targetState.shadowOffset = shadowOffset } } /** Set the shadowRadius for the view to animate from/to. - Parameters: - shadowRadius: shadowRadius for the view to animate from/to */ public static func shadowRadius(_ shadowRadius: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.shadowRadius = shadowRadius } } /** Set the shadowPath for the view to animate from/to. - Parameters: - shadowPath: shadowPath for the view to animate from/to */ public static func shadowPath(_ shadowPath: CGPath) -> HeroModifier { return HeroModifier { targetState in targetState.shadowPath = shadowPath } } /** Set the masksToBounds for the view to animate from/to. - Parameters: - masksToBounds: masksToBounds for the view to animate from/to */ public static func masksToBounds(_ masksToBounds: Bool) -> HeroModifier { return HeroModifier { targetState in targetState.masksToBounds = masksToBounds } } } // timing modifiers extension HeroModifier { /** Sets the duration of the animation for a given view. If not used, Hero will use determine the duration based on the distance and size changes. - Parameters: - duration: duration of the animation Note: a duration of .infinity means matching the duration of the longest animation. same as .durationMatchLongest */ public static func duration(_ duration: TimeInterval) -> HeroModifier { return HeroModifier { targetState in targetState.duration = duration } } /** Sets the duration of the animation for a given view to match the longest animation of the transition. */ public static var durationMatchLongest: HeroModifier = HeroModifier { targetState in targetState.duration = .infinity } /** Sets the delay of the animation for a given view. - Parameters: - delay: delay of the animation */ public static func delay(_ delay: TimeInterval) -> HeroModifier { return HeroModifier { targetState in targetState.delay = delay } } /** Sets the timing function of the animation for a given view. If not used, Hero will use determine the timing function based on whether or not the view is entering or exiting the screen. - Parameters: - timingFunction: timing function of the animation */ public static func timingFunction(_ timingFunction: CAMediaTimingFunction) -> HeroModifier { return HeroModifier { targetState in targetState.timingFunction = timingFunction } } /** (iOS 9+) Use spring animation with custom stiffness & damping. The duration will be automatically calculated. Will be ignored if arc, timingFunction, or duration is set. - Parameters: - stiffness: stiffness of the spring - damping: damping of the spring */ @available(iOS 9, *) public static func spring(stiffness: CGFloat, damping: CGFloat) -> HeroModifier { return HeroModifier { targetState in targetState.spring = (stiffness, damping) } } } // other modifiers extension HeroModifier { /** Transition from/to the state of the view with matching heroID Will also force the view to use global coordinate space. The following layer properties will be animated from the given view. position bounds.size cornerRadius transform shadowColor shadowOpacity shadowOffset shadowRadius shadowPath Note that the following properties **won't** be taken from the source view. backgroundColor borderWidth borderColor - Parameters: - heroID: the source view's heroId. */ public static func source(heroID: String) -> HeroModifier { return HeroModifier { targetState in targetState.source = heroID } } /** Works in combination with position modifier to apply a natural curve when moving to the destination. */ public static var arc: HeroModifier = .arc() /** Works in combination with position modifier to apply a natural curve when moving to the destination. - Parameters: - intensity: a value of 1 represent a downward natural curve ╰. a value of -1 represent a upward curve ╮. default is 1. */ public static func arc(intensity: CGFloat = 1) -> HeroModifier { return HeroModifier { targetState in targetState.arc = intensity } } /** Cascade applys increasing delay modifiers to subviews */ public static var cascade: HeroModifier = .cascade() /** Cascade applys increasing delay modifiers to subviews - Parameters: - delta: delay in between each animation - direction: cascade direction - delayMatchedViews: whether or not to delay matched subviews until all cascading animation have started */ public static func cascade(delta: TimeInterval = 0.02, direction: CascadeDirection = .topToBottom, delayMatchedViews: Bool = false) -> HeroModifier { return HeroModifier { targetState in targetState.cascade = (delta, direction, delayMatchedViews) } } } // conditional modifiers extension HeroModifier { /** Apply modifiers only if the condition return true. */ public static func when(_ condition: @escaping (HeroConditionalContext) -> Bool, _ modifiers: [HeroModifier]) -> HeroModifier { return HeroModifier { targetState in if targetState.conditionalModifiers == nil { targetState.conditionalModifiers = [] } targetState.conditionalModifiers!.append((condition, modifiers)) } } public static func when(_ condition: @escaping (HeroConditionalContext) -> Bool, _ modifiers: HeroModifier...) -> HeroModifier { return .when(condition, modifiers) } public static func whenMatched(_ modifiers: HeroModifier...) -> HeroModifier { return .when({ $0.isMatched }, modifiers) } public static func whenPresenting(_ modifiers: HeroModifier...) -> HeroModifier { return .when({ $0.isPresenting }, modifiers) } public static func whenDismissing(_ modifiers: HeroModifier...) -> HeroModifier { return .when({ !$0.isPresenting }, modifiers) } public static func whenAppearing(_ modifiers: HeroModifier...) -> HeroModifier { return .when({ $0.isAppearing }, modifiers) } public static func whenDisappearing(_ modifiers: HeroModifier...) -> HeroModifier { return .when({ !$0.isAppearing }, modifiers) } } #endif ================================================ FILE: Sources/HeroPlugin.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit open class HeroPlugin: NSObject, HeroPreprocessor, HeroAnimator { weak public var hero: HeroTransition! public var context: HeroContext! { return hero.context } /** Determines whether or not to receive `seekTo` callback on every frame. Default is false. When **requirePerFrameCallback** is **false**, the plugin needs to start its own animations inside `animate` & `resume` The `seekTo` method is only being called during an interactive transition. When **requirePerFrameCallback** is **true**, the plugin will receive `seekTo` callback on every animation frame. Hence it is possible for the plugin to do per-frame animations without implementing `animate` & `resume` */ open var requirePerFrameCallback = false public override required init() {} /** Called before any animation. Override this method when you want to preprocess modifiers for views - Parameters: - context: object holding all parsed and changed modifiers, - fromViews: A flattened list of all views from source ViewController - toViews: A flattened list of all views from destination ViewController To check a view's modifiers: context[view] context[view, "modifierName"] To set a view's modifiers: context[view] = [("modifier1", ["parameter1"]), ("modifier2", [])] context[view, "modifier1"] = ["parameter1", "parameter2"] */ open func process(fromViews: [UIView], toViews: [UIView]) {} /** - Returns: return true if the plugin can handle animating the view. - Parameters: - context: object holding all parsed and changed modifiers, - view: the view to check whether or not the plugin can handle the animation - appearing: true if the view is appearing(i.e. a view in destination ViewController) If return true, Hero won't animate and won't let any other plugins animate this view. The view will also be hidden automatically during the animation. */ open func canAnimate(view: UIView, appearing: Bool) -> Bool { return false } /** Perform the animation. Note: views in `fromViews` & `toViews` are hidden already. Unhide then if you need to take snapshots. - Parameters: - context: object holding all parsed and changed modifiers, - fromViews: A flattened list of all views from source ViewController (filtered by `canAnimate`) - toViews: A flattened list of all views from destination ViewController (filtered by `canAnimate`) - Returns: The duration needed to complete the animation */ open func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { return 0 } /** Called when all animations are completed. Should perform cleanup and release any reference */ open func clean() {} /** For supporting interactive animation only. This method is called when an interactive animation is in place The plugin should pause the animation, and seek to the given progress - Parameters: - timePassed: time of the animation to seek to. */ open func seekTo(timePassed: TimeInterval) {} /** For supporting interactive animation only. This method is called when an interactive animation is ended The plugin should resume the animation. - Parameters: - timePassed: will be the same value since last `seekTo` - reverse: a boolean value indicating whether or not the animation should reverse */ open func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { return 0 } /** For supporting interactive animation only. This method is called when user wants to override animation modifiers during an interactive animation - Parameters: - state: the target state to override - view: the view to override */ open func apply(state: HeroTargetState, to view: UIView) {} open func changeTarget(state: HeroTargetState, isDestination: Bool, to view: UIView) {} } // methods for enable/disable the current plugin extension HeroPlugin { public static var isEnabled: Bool { get { return HeroTransition.isEnabled(plugin: self) } set { if newValue { enable() } else { disable() } } } public static func enable() { HeroTransition.enable(plugin: self) } public static func disable() { HeroTransition.disable(plugin: self) } } // MARK: Plugin Support internal extension HeroTransition { static func isEnabled(plugin: HeroPlugin.Type) -> Bool { return enabledPlugins.firstIndex(where: { return $0 == plugin}) != nil } static func enable(plugin: HeroPlugin.Type) { disable(plugin: plugin) enabledPlugins.append(plugin) } static func disable(plugin: HeroPlugin.Type) { if let index = enabledPlugins.firstIndex(where: { return $0 == plugin}) { enabledPlugins.remove(at: index) } } } #endif ================================================ FILE: Sources/HeroTargetState.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import CoreGraphics import QuartzCore public enum HeroSnapshotType { /// Will optimize for different type of views /// For custom views or views with masking, .optimizedDefault might create snapshots /// that appear differently than the actual view. /// In that case, use .normal or .slowRender to disable the optimization case optimized /// snapshotView(afterScreenUpdates:) case normal /// layer.render(in: currentContext) case layerRender /// will not create snapshot. animate the view directly. /// This will mess up the view hierarchy, therefore, view controllers have to rebuild /// its view structure after the transition finishes case noSnapshot } public enum HeroCoordinateSpace { case global case local } public struct HeroTargetState { public var beginState: [HeroModifier]? public var conditionalModifiers: [((HeroConditionalContext) -> Bool, [HeroModifier])]? public var position: CGPoint? public var size: CGSize? public var transform: CATransform3D? public var opacity: Float? public var cornerRadius: CGFloat? public var backgroundColor: CGColor? public var zPosition: CGFloat? public var anchorPoint: CGPoint? public var contentsRect: CGRect? public var contentsScale: CGFloat? public var borderWidth: CGFloat? public var borderColor: CGColor? public var shadowColor: CGColor? public var shadowOpacity: Float? public var shadowOffset: CGSize? public var shadowRadius: CGFloat? public var shadowPath: CGPath? public var masksToBounds: Bool? public var displayShadow: Bool = true public var overlay: (color: CGColor, opacity: CGFloat)? public var spring: (CGFloat, CGFloat)? public var delay: TimeInterval = 0 public var duration: TimeInterval? public var timingFunction: CAMediaTimingFunction? public var arc: CGFloat? public var source: String? public var cascade: (TimeInterval, CascadeDirection, Bool)? public var ignoreSubviewModifiers: Bool? public var coordinateSpace: HeroCoordinateSpace? public var useScaleBasedSizeChange: Bool? public var snapshotType: HeroSnapshotType? public var nonFade: Bool = false public var forceAnimate: Bool = false public var custom: [String: Any]? init(modifiers: [HeroModifier]) { append(contentsOf: modifiers) } public mutating func append(_ modifier: HeroModifier) { modifier.apply(&self) } public mutating func append(contentsOf modifiers: [HeroModifier]) { for modifier in modifiers { modifier.apply(&self) } } /** - Returns: custom item for a specific key */ public subscript(key: String) -> Any? { get { return custom?[key] } set { if custom == nil { custom = [:] } custom![key] = newValue } } } extension HeroTargetState: ExpressibleByArrayLiteral { public init(arrayLiteral elements: HeroModifier...) { append(contentsOf: elements) } } #endif ================================================ FILE: Sources/HeroTypes.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit public protocol HeroPreprocessor: AnyObject { var hero: HeroTransition! { get set } func process(fromViews: [UIView], toViews: [UIView]) } public protocol HeroAnimator: AnyObject { var hero: HeroTransition! { get set } func canAnimate(view: UIView, appearing: Bool) -> Bool func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval func clean() func seekTo(timePassed: TimeInterval) func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval func apply(state: HeroTargetState, to view: UIView) func changeTarget(state: HeroTargetState, isDestination: Bool, to view: UIView) } public protocol HeroProgressUpdateObserver: AnyObject { func heroDidUpdateProgress(progress: Double) } public enum HeroViewOrderingStrategy { case auto, sourceViewOnTop, destinationViewOnTop } #endif ================================================ FILE: Sources/HeroViewControllerDelegate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit @objc public protocol HeroViewControllerDelegate { @objc optional func heroWillStartAnimatingFrom(viewController: UIViewController) @objc optional func heroDidEndAnimatingFrom(viewController: UIViewController) @objc optional func heroDidCancelAnimatingFrom(viewController: UIViewController) @objc optional func heroWillStartTransition() @objc optional func heroDidEndTransition() @objc optional func heroDidCancelTransition() @objc optional func heroWillStartAnimatingTo(viewController: UIViewController) @objc optional func heroDidEndAnimatingTo(viewController: UIViewController) @objc optional func heroDidCancelAnimatingTo(viewController: UIViewController) } // delegate helper internal extension HeroTransition { func closureProcessForHeroDelegate(vc: T, closure: (HeroViewControllerDelegate) -> Void) { if let delegate = vc as? HeroViewControllerDelegate { closure(delegate) } if let navigationController = vc as? UINavigationController, let delegate = navigationController.topViewController as? HeroViewControllerDelegate { closure(delegate) } else if let tabBarController = vc as? UITabBarController, let delegate = tabBarController.selectedViewController as? HeroViewControllerDelegate { closure(delegate) } else { for vc in vc.children where vc.isViewLoaded { self.closureProcessForHeroDelegate(vc: vc, closure: closure) } } } } #endif ================================================ FILE: Sources/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: Sources/Parser/HeroStringConvertible.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation public protocol HeroStringConvertible { static func from(node: ExprNode) -> Self? } extension String { func parse() -> [T]? { let lexer = Lexer(input: self) let parser = Parser(tokens: lexer.tokenize()) do { let nodes = try parser.parse() var results = [T]() for node in nodes { if let modifier = T.from(node: node) { results.append(modifier) } else { print("\(node.name) doesn't exist in \(T.self)") } } return results } catch let error { print("failed to parse \"\(self)\", error: \(error)") } return nil } func parseOne() -> T? { return parse()?.last } } ================================================ FILE: Sources/Parser/Lexer.swift ================================================ // // Lexer.swift // Kaleidoscope // // Created by Matthew Cheok on 15/11/15. // Copyright © 2015 Matthew Cheok. All rights reserved. // import Foundation public enum Token { case identifier(String, CountableRange) case number(Float, CountableRange) case parensOpen(CountableRange) case parensClose(CountableRange) case comma(CountableRange) case other(String, CountableRange) } typealias TokenGenerator = (String, CountableRange) -> Token? let tokenList: [(String, TokenGenerator)] = [ ("[ \t\n]", { _, _ in nil }), ("[a-zA-Z][a-zA-Z0-9]*", { .identifier($0, $1) }), ("\\-?[0-9.]+", { .number(Float($0)!, $1) }), ("\\(", { .parensOpen($1) }), ("\\)", { .parensClose($1) }), (",", { .comma($1) }) ] public class Lexer { let input: String public init(input: String) { self.input = input } public func tokenize() -> [Token] { var tokens = [Token]() var content = input while !content.isEmpty { var matched = false for (pattern, generator) in tokenList { if let (m, r) = content.match(regex: pattern) { if let t = generator(m, r) { tokens.append(t) } content = String(content[content.index(content.startIndex, offsetBy: m.count)...]) matched = true break } } if !matched { let index = content.index(content.startIndex, offsetBy: 1) let intIndex = content.distance(from: content.startIndex, to: index) tokens.append(.other(String(content[.. = 0..<0 public let name: String public var description: String { return "ExprNode(name: \"\(name)\")" } public init(name: String) { self.name = name } } public func == (lhs: ExprNode, rhs: ExprNode) -> Bool { return lhs.description == rhs.description } public class NumberNode: ExprNode { public let value: Float public override var description: String { return "NumberNode(value: \(value))" } public init(value: Float) { self.value = value super.init(name: "\(value)") } } public class VariableNode: ExprNode { public override var description: String { return "VariableNode(name: \"\(name)\")" } } public class BinaryOpNode: ExprNode { public let lhs: ExprNode public let rhs: ExprNode public override var description: String { return "BinaryOpNode(name: \"\(name)\", lhs: \(lhs), rhs: \(rhs))" } public init(name: String, lhs: ExprNode, rhs: ExprNode) { self.lhs = lhs self.rhs = rhs super.init(name: "\(name)") } } public class CallNode: ExprNode { public let arguments: [ExprNode] public override var description: String { return "CallNode(name: \"\(name)\", arguments: \(arguments))" } public init(name: String, arguments: [ExprNode]) { self.arguments = arguments super.init(name: "\(name)") } } public class PrototypeNode: ExprNode { public let argumentNames: [String] public override var description: String { return "PrototypeNode(name: \"\(name)\", argumentNames: \(argumentNames))" } public init(name: String, argumentNames: [String]) { self.argumentNames = argumentNames super.init(name: "\(name)") } } public class FunctionNode: ExprNode { public let prototype: PrototypeNode public let body: ExprNode public override var description: String { return "FunctionNode(prototype: \(prototype), body: \(body))" } public init(prototype: PrototypeNode, body: ExprNode) { self.prototype = prototype self.body = body super.init(name: "\(prototype.name)") } } ================================================ FILE: Sources/Parser/Parser.swift ================================================ // // Parser.swift // Kaleidoscope // // Created by Matthew Cheok on 15/11/15. // Copyright © 2015 Matthew Cheok. All rights reserved. // import Foundation public enum ParseError: Error { case unexpectToken case undefinedOperator(String) case expectCharacter(Character) case expectExpression case expectArgumentList case expectFunctionName } public class Parser { let tokens: [Token] var index = 0 public init(tokens: [Token]) { self.tokens = tokens } func peekCurrentToken() -> Token { if index >= tokens.count { return .other("", 0..<0) } return tokens[index] } @discardableResult func popCurrentToken() -> Token { defer { index += 1 } return tokens[index] } func parseNumber() throws -> ExprNode { guard case let .number(value, _) = popCurrentToken() else { throw ParseError.unexpectToken } return NumberNode(value: value) } func parseExpression() throws -> ExprNode { let node = try parsePrimary() return try parseBinaryOp(node: node) } func parseParens() throws -> ExprNode { guard case .parensOpen = popCurrentToken() else { throw ParseError.expectCharacter("(") } let exp = try parseExpression() guard case .parensClose = popCurrentToken() else { throw ParseError.expectCharacter(")") } return exp } func parseIdentifier() throws -> ExprNode { guard case let .identifier(name, _) = popCurrentToken() else { throw ParseError.unexpectToken } guard case .parensOpen = peekCurrentToken() else { return VariableNode(name: name) } popCurrentToken() var arguments = [ExprNode]() if case .parensClose = peekCurrentToken() { } else { while true { let argument = try parseExpression() arguments.append(argument) if case .parensClose = peekCurrentToken() { break } guard case .comma = popCurrentToken() else { throw ParseError.expectArgumentList } } } popCurrentToken() return CallNode(name: name, arguments: arguments) } func parsePrimary() throws -> ExprNode { switch peekCurrentToken() { case .identifier: return try parseIdentifier() case .number: return try parseNumber() case .parensOpen: return try parseParens() default: throw ParseError.expectExpression } } let operatorPrecedence: [String: Int] = [ "+": 20, "-": 20, "*": 40, "/": 40 ] func getCurrentTokenPrecedence() throws -> Int { guard index < tokens.count else { return -1 } guard case let .other(op, _) = peekCurrentToken() else { return -1 } guard let precedence = operatorPrecedence[op] else { throw ParseError.undefinedOperator(op) } return precedence } func parseBinaryOp(node: ExprNode, exprPrecedence: Int = 0) throws -> ExprNode { var lhs = node while true { let tokenPrecedence = try getCurrentTokenPrecedence() if tokenPrecedence < exprPrecedence { return lhs } guard case let .other(op, _) = popCurrentToken() else { throw ParseError.unexpectToken } var rhs = try parsePrimary() let nextPrecedence = try getCurrentTokenPrecedence() if tokenPrecedence < nextPrecedence { rhs = try parseBinaryOp(node: rhs, exprPrecedence: tokenPrecedence+1) } lhs = BinaryOpNode(name: op, lhs: lhs, rhs: rhs) } } public func parse() throws -> [ExprNode] { index = 0 var nodes = [ExprNode]() while index < tokens.count { let expr = try parsePrimary() nodes.append(expr) } return nodes } } ================================================ FILE: Sources/Parser/Regex.swift ================================================ // // Regex.swift // Kaleidoscope // // Created by Matthew Cheok on 15/11/15. // Copyright © 2015 Matthew Cheok. All rights reserved. // import Foundation var expressions = [String: NSRegularExpression]() public extension String { func match(regex: String) -> (String, CountableRange)? { let expression: NSRegularExpression if let exists = expressions[regex] { expression = exists } else { do { expression = try NSRegularExpression(pattern: "^\(regex)", options: []) expressions[regex] = expression } catch { return nil } } let range = expression.rangeOfFirstMatch(in: self, options: [], range: NSRange(0 ..< self.utf16.count)) if range.location != NSNotFound { return ((self as NSString).substring(with: range), range.location ..< range.location + range.length ) } return nil } } ================================================ FILE: Sources/Preprocessors/BasePreprocessor.swift ================================================ // // CascadeEffect.swift // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit class BasePreprocessor: HeroPreprocessor { weak public var hero: HeroTransition! public var context: HeroContext! { return hero?.context } func process(fromViews: [UIView], toViews: [UIView]) {} } #endif ================================================ FILE: Sources/Preprocessors/CascadePreprocessor.swift ================================================ // // CascadeEffect.swift // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit public enum CascadeDirection { case topToBottom case bottomToTop case leftToRight case rightToLeft case radial(center: CGPoint) case inverseRadial(center: CGPoint) var comparator: (UIView, UIView) -> Bool { switch self { case .topToBottom: return topToBottomComperator case .bottomToTop: return bottomToTopComperator case .leftToRight: return leftToRightComperator case .rightToLeft: return rightToLeftComperator case .radial(let center): return { (lhs: UIView, rhs: UIView) -> Bool in return lhs.center.distance(center) < rhs.center.distance(center) } case .inverseRadial(let center): return { (lhs: UIView, rhs: UIView) -> Bool in return lhs.center.distance(center) > rhs.center.distance(center) } } } init?(_ string: String) { switch string { case "bottomToTop": self = .bottomToTop case "leftToRight": self = .leftToRight case "rightToLeft": self = .rightToLeft case "topToBottom": self = .topToBottom case "leadingToTrailing": self = .leadingToTrailing case "trailingToLeading": self = .trailingToLeading default: return nil } } public static var leadingToTrailing: CascadeDirection { return !Locale.isDeviceLanguageRightToLeft ? .leftToRight : .rightToLeft } public static var trailingToLeading: CascadeDirection { return !Locale.isDeviceLanguageRightToLeft ? .rightToLeft : .leftToRight } private func topToBottomComperator(lhs: UIView, rhs: UIView) -> Bool { return lhs.frame.minY < rhs.frame.minY } private func bottomToTopComperator(lhs: UIView, rhs: UIView) -> Bool { return lhs.frame.maxY == rhs.frame.maxY ? lhs.frame.maxX > rhs.frame.maxX : lhs.frame.maxY > rhs.frame.maxY } private func leftToRightComperator(lhs: UIView, rhs: UIView) -> Bool { return lhs.frame.minX < rhs.frame.minX } private func rightToLeftComperator(lhs: UIView, rhs: UIView) -> Bool { return lhs.frame.maxX > rhs.frame.maxX } } class CascadePreprocessor: BasePreprocessor { override func process(fromViews: [UIView], toViews: [UIView]) { process(views: fromViews) process(views: toViews) } func process(views: [UIView]) { for view in views { guard let (deltaTime, direction, delayMatchedViews) = context[view]?.cascade else { continue } var parentView = view if view is UITableView, let wrapperView = view.subviews.get(0) { parentView = wrapperView } let sortedSubviews = parentView.subviews.sorted(by: direction.comparator) let initialDelay = context[view]!.delay let finalDelay = TimeInterval(sortedSubviews.count) * deltaTime + initialDelay for (i, subview) in sortedSubviews.enumerated() { let delay = TimeInterval(i) * deltaTime + initialDelay func applyDelay(view: UIView) { if context.pairedView(for: view) == nil { context[view]?.delay = delay } else if delayMatchedViews, let paired = context.pairedView(for: view) { context[view]?.delay = finalDelay context[paired]?.delay = finalDelay } for subview in view.subviews { applyDelay(view: subview) } } applyDelay(view: subview) } } } } #endif ================================================ FILE: Sources/Preprocessors/ConditionalPreprocessor.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit public struct HeroConditionalContext { internal weak var hero: HeroTransition! public weak var view: UIView! public private(set) var isAppearing: Bool public var isPresenting: Bool { return hero.isPresenting } public var isInTabbarController: Bool { return hero.inTabBarController } public var isInNavbarController: Bool { return hero.inNavigationController } public var isMatched: Bool { return matchedView != nil } public var isAncestorViewMatched: Bool { return matchedAncestorView != nil } public var matchedView: UIView? { return hero.context.pairedView(for: view) } public var matchedAncestorView: (UIView, UIView)? { var current = view.superview while let ancestor = current, ancestor != hero.context.container { if let pairedView = hero.context.pairedView(for: ancestor) { return (ancestor, pairedView) } current = ancestor.superview } return nil } public var fromViewController: UIViewController { return hero.fromViewController! } public var toViewController: UIViewController { return hero.toViewController! } public var currentViewController: UIViewController { return isAppearing ? toViewController : fromViewController } public var otherViewController: UIViewController { return isAppearing ? fromViewController : toViewController } } class ConditionalPreprocessor: BasePreprocessor { override func process(fromViews: [UIView], toViews: [UIView]) { process(views: fromViews, appearing: false) process(views: toViews, appearing: true) } func process(views: [UIView], appearing: Bool) { for view in views { guard let conditionalModifiers = context[view]?.conditionalModifiers else { continue } for (condition, modifiers) in conditionalModifiers { if condition(HeroConditionalContext(hero: hero, view: view, isAppearing: appearing)) { context[view]!.append(contentsOf: modifiers) } } } } } #endif ================================================ FILE: Sources/Preprocessors/DefaultAnimationPreprocessor.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit public enum HeroDefaultAnimationType { public enum Direction: HeroStringConvertible { case left, right, up, down public static func from(node: ExprNode) -> Direction? { switch node.name { case "left": return .left case "right": return .right case "up": return .up case "down": return .down case "leading": return .leading case "trailing": return .trailing default: return nil } } public static var leadingToTrailing: CascadeDirection { return !Locale.isDeviceLanguageRightToLeft ? .leftToRight : .rightToLeft } public static var trailingToLeading: CascadeDirection { return !Locale.isDeviceLanguageRightToLeft ? .rightToLeft : .leftToRight } public static var leading: Direction { return !Locale.isDeviceLanguageRightToLeft ? .left : .right } public static var trailing: Direction { return !Locale.isDeviceLanguageRightToLeft ? .right : .left } } public enum Strategy { case forceLeftToRight, forceRightToLeft, userInterface func defaultDirection(presenting: Bool) -> Direction { switch self { case .forceLeftToRight: return presenting ? .left : .right case .forceRightToLeft: return presenting ? .right : .left case .userInterface: return presenting ? .leading : .trailing } } } case auto case push(direction: Direction) case pull(direction: Direction) case cover(direction: Direction) case uncover(direction: Direction) case slide(direction: Direction) case zoomSlide(direction: Direction) case pageIn(direction: Direction) case pageOut(direction: Direction) case fade case zoom case zoomOut indirect case selectBy(presenting: HeroDefaultAnimationType, dismissing: HeroDefaultAnimationType) public static func autoReverse(presenting: HeroDefaultAnimationType) -> HeroDefaultAnimationType { return .selectBy(presenting: presenting, dismissing: presenting.reversed()) } case none func reversed() -> HeroDefaultAnimationType { switch self { case .push(direction: .up): return .pull(direction: .down) case .push(direction: .right): return .pull(direction: .left) case .push(direction: .down): return .pull(direction: .up) case .push(direction: .left): return .pull(direction: .right) case .pull(direction: .up): return .push(direction: .down) case .pull(direction: .right): return .push(direction: .left) case .pull(direction: .down): return .push(direction: .up) case .pull(direction: .left): return .push(direction: .right) case .cover(direction: .up): return .uncover(direction: .down) case .cover(direction: .right): return .uncover(direction: .left) case .cover(direction: .down): return .uncover(direction: .up) case .cover(direction: .left): return .uncover(direction: .right) case .uncover(direction: .up): return .cover(direction: .down) case .uncover(direction: .right): return .cover(direction: .left) case .uncover(direction: .down): return .cover(direction: .up) case .uncover(direction: .left): return .cover(direction: .right) case .slide(direction: .up): return .slide(direction: .down) case .slide(direction: .down): return .slide(direction: .up) case .slide(direction: .left): return .slide(direction: .right) case .slide(direction: .right): return .slide(direction: .left) case .zoomSlide(direction: .up): return .zoomSlide(direction: .down) case .zoomSlide(direction: .down): return .zoomSlide(direction: .up) case .zoomSlide(direction: .left): return .zoomSlide(direction: .right) case .zoomSlide(direction: .right): return .zoomSlide(direction: .left) case .pageIn(direction: .up): return .pageOut(direction: .down) case .pageIn(direction: .right): return .pageOut(direction: .left) case .pageIn(direction: .down): return .pageOut(direction: .up) case .pageIn(direction: .left): return .pageOut(direction: .right) case .pageOut(direction: .up): return .pageIn(direction: .down) case .pageOut(direction: .right): return .pageIn(direction: .left) case .pageOut(direction: .down): return .pageIn(direction: .up) case .pageOut(direction: .left): return .pageIn(direction: .right) case .zoom: return .zoomOut case .zoomOut: return .zoom default: return self } } public var label: String? { let mirror = Mirror(reflecting: self) if let associated = mirror.children.first { let valuesMirror = Mirror(reflecting: associated.value) if !valuesMirror.children.isEmpty { let parameters = valuesMirror.children.map { ".\($0.value)" }.joined(separator: ",") return ".\(associated.label ?? "")(\(parameters))" } return ".\(associated.label ?? "")(.\(associated.value))" } return ".\(self)" } } extension HeroDefaultAnimationType: HeroStringConvertible { public static func from(node: ExprNode) -> HeroDefaultAnimationType? { let name: String = node.name let parameters: [ExprNode] = (node as? CallNode)?.arguments ?? [] switch name { case "auto": return .auto case "push": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .push(direction: direction) } case "pull": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .pull(direction: direction) } case "cover": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .cover(direction: direction) } case "uncover": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .uncover(direction: direction) } case "slide": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .slide(direction: direction) } case "zoomSlide": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .zoomSlide(direction: direction) } case "pageIn": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .pageIn(direction: direction) } case "pageOut": if let node = parameters.get(0), let direction = Direction.from(node: node) { return .pageOut(direction: direction) } case "fade": return .fade case "zoom": return .zoom case "zoomOut": return .zoomOut case "selectBy": if let presentingNode = parameters.get(0), let presenting = HeroDefaultAnimationType.from(node: presentingNode), let dismissingNode = parameters.get(1), let dismissing = HeroDefaultAnimationType.from(node: dismissingNode) { return .selectBy(presenting: presenting, dismissing: dismissing) } case "none": return HeroDefaultAnimationType.none default: break } return nil } } class DefaultAnimationPreprocessor: BasePreprocessor { func shift(direction: HeroDefaultAnimationType.Direction, appearing: Bool, size: CGSize? = nil, transpose: Bool = false) -> CGPoint { let size = size ?? context.container.bounds.size let rtn: CGPoint switch direction { case .left, .right: rtn = CGPoint(x: (direction == .right) == appearing ? -size.width : size.width, y: 0) case .up, .down: rtn = CGPoint(x: 0, y: (direction == .down) == appearing ? -size.height : size.height) } if transpose { return CGPoint(x: rtn.y, y: rtn.x) } return rtn } override func process(fromViews: [UIView], toViews: [UIView]) { guard let hero = hero, let toView = hero.toView, let fromView = hero.fromView else { return } var defaultAnimation = hero.defaultAnimation let inNavigationController = hero.inNavigationController let inTabBarController = hero.inTabBarController let toViewController = hero.toViewController let fromViewController = hero.fromViewController let presenting = hero.isPresenting let fromOverFullScreen = hero.fromOverFullScreen let toOverFullScreen = hero.toOverFullScreen let animators = hero.animators if case .auto = defaultAnimation { if inNavigationController, let navAnim = toViewController?.navigationController?.hero.navigationAnimationType { defaultAnimation = navAnim } else if inTabBarController, let tabAnim = toViewController?.tabBarController?.hero.tabBarAnimationType { defaultAnimation = tabAnim } else if let modalAnim = (presenting ? toViewController : fromViewController)?.hero.modalAnimationType { defaultAnimation = modalAnim } } if case .selectBy(let presentAnim, let dismissAnim) = defaultAnimation { defaultAnimation = presenting ? presentAnim : dismissAnim } if case .auto = defaultAnimation { if animators.contains(where: { $0.canAnimate(view: toView, appearing: true) || $0.canAnimate(view: fromView, appearing: false) }) { defaultAnimation = .none } else if inNavigationController { let direction = hero.defaultAnimationDirectionStrategy.defaultDirection(presenting: presenting) defaultAnimation = .push(direction: direction) } else if inTabBarController { let direction = hero.defaultAnimationDirectionStrategy.defaultDirection(presenting: presenting) defaultAnimation = .slide(direction: direction) } else { defaultAnimation = .fade } } if case .none = defaultAnimation { return } context[fromView] = [.timingFunction(.standard), .duration(0.35)] context[toView] = [.timingFunction(.standard), .duration(0.35)] let shadowState: [HeroModifier] = [.shadowOpacity(0.5), .shadowColor(.black), .shadowRadius(5), .shadowOffset(.zero), .masksToBounds(false)] switch defaultAnimation { case .push(let direction): context.insertToViewFirst = false context[toView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: true)), .shadowOpacity(0), .beginWith(modifiers: shadowState), .timingFunction(.deceleration)]) context[fromView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: false) / 3), .overlay(color: .black, opacity: 0.1), .timingFunction(.deceleration)]) case .pull(let direction): context.insertToViewFirst = true context[fromView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: false)), .shadowOpacity(0), .beginWith(modifiers: shadowState)]) context[toView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: true) / 3), .overlay(color: .black, opacity: 0.1)]) case .slide(let direction): context[fromView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: false))]) context[toView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: true))]) case .zoomSlide(let direction): context[fromView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: false)), .scale(0.8)]) context[toView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: true)), .scale(0.8)]) case .cover(let direction): context.insertToViewFirst = false context[toView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: true)), .shadowOpacity(0), .beginWith(modifiers: shadowState), .timingFunction(.deceleration)]) context[fromView]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1), .timingFunction(.deceleration)]) case .uncover(let direction): context.insertToViewFirst = true context[fromView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: false)), .shadowOpacity(0), .beginWith(modifiers: shadowState)]) context[toView]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1)]) case .pageIn(let direction): context.insertToViewFirst = false context[toView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: true)), .shadowOpacity(0), .beginWith(modifiers: shadowState), .timingFunction(.deceleration)]) context[fromView]!.append(contentsOf: [.scale(0.7), .overlay(color: .black, opacity: 0.1), .timingFunction(.deceleration)]) case .pageOut(let direction): context.insertToViewFirst = true context[fromView]!.append(contentsOf: [.translate(shift(direction: direction, appearing: false)), .shadowOpacity(0), .beginWith(modifiers: shadowState)]) context[toView]!.append(contentsOf: [.scale(0.7), .overlay(color: .black, opacity: 0.1)]) case .fade: // TODO: clean up this. overFullScreen logic shouldn't be here if !(fromOverFullScreen && !presenting) { context[toView] = [.fade] } #if os(tvOS) context[fromView] = [.fade] #else if (!presenting && toOverFullScreen) || !fromView.isOpaque || (fromView.backgroundColor?.alphaComponent ?? 1) < 1 { context[fromView] = [.fade] } #endif context[toView]!.append(.durationMatchLongest) context[fromView]!.append(.durationMatchLongest) case .zoom: context.insertToViewFirst = true context[fromView]!.append(contentsOf: [.scale(1.3), .fade]) context[toView]!.append(contentsOf: [.scale(0.7)]) case .zoomOut: context.insertToViewFirst = false context[toView]!.append(contentsOf: [.scale(1.3), .fade]) context[fromView]!.append(contentsOf: [.scale(0.7)]) default: fatalError("Not implemented") } } } #endif ================================================ FILE: Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit class IgnoreSubviewModifiersPreprocessor: BasePreprocessor { override func process(fromViews: [UIView], toViews: [UIView]) { process(views: fromViews) process(views: toViews) } func process(views: [UIView]) { for view in views { guard let recursive = context[view]?.ignoreSubviewModifiers else { continue } var parentView = view if view is UITableView, let wrapperView = view.subviews.get(0) { parentView = wrapperView } if recursive { cleanSubviewModifiers(parentView) } else { for subview in parentView.subviews { context[subview] = nil } } } } private func cleanSubviewModifiers(_ parentView: UIView) { for view in parentView.subviews { context[view] = nil cleanSubviewModifiers(view) } } } #endif ================================================ FILE: Sources/Preprocessors/MatchPreprocessor.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit class MatchPreprocessor: BasePreprocessor { override func process(fromViews: [UIView], toViews: [UIView]) { for tv in toViews { guard let id = tv.hero.id, let fv = context.sourceView(for: id) else { continue } var tvState = context[tv] ?? HeroTargetState() var fvState = context[fv] ?? HeroTargetState() // match is just a two-way source effect tvState.source = id fvState.source = id fvState.arc = tvState.arc fvState.duration = tvState.duration fvState.timingFunction = tvState.timingFunction fvState.delay = tvState.delay fvState.spring = tvState.spring let forceNonFade = tvState.nonFade || fvState.nonFade let isNonOpaque = !fv.isOpaque || fv.alpha < 1 || !tv.isOpaque || tv.alpha < 1 if context.insertToViewFirst { fvState.opacity = 0 if !forceNonFade && isNonOpaque { tvState.opacity = 0 } else { tvState.opacity = nil if !tv.layer.masksToBounds && tvState.displayShadow { fvState.displayShadow = false } } } else { tvState.opacity = 0 if !forceNonFade && isNonOpaque { // cross fade if from/toViews are not opaque fvState.opacity = 0 } else { // no cross fade in this case, fromView is always displayed during the transition. fvState.opacity = nil // we dont want two shadows showing up. Therefore we disable toView's shadow when fromView is able to display its shadow if !fv.layer.masksToBounds && fvState.displayShadow { tvState.displayShadow = false } } } context[tv] = tvState context[fv] = fvState } } } #endif ================================================ FILE: Sources/Preprocessors/SourcePreprocessor.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit class SourcePreprocessor: BasePreprocessor { override func process(fromViews: [UIView], toViews: [UIView]) { for fv in fromViews { guard let id = context[fv]?.source, let tv = context.destinationView(for: id) else { continue } prepareFor(view: fv, targetView: tv) } for tv in toViews { guard let id = context[tv]?.source, let fv = context.sourceView(for: id) else { continue } prepareFor(view: tv, targetView: fv) } } func prepareFor(view: UIView, targetView: UIView) { let targetPos = context.container.convert(targetView.layer.position, from: targetView.superview!) let targetTransform = context.container.layer.flatTransformTo(layer: targetView.layer) var state = context[view]! // use global coordinate space since over target position is converted from the global container state.coordinateSpace = .global state.position = targetPos state.transform = targetTransform // remove incompatible options state.size = nil if view.bounds.size != targetView.bounds.size { state.size = targetView.bounds.size } if state.cornerRadius == nil, view.layer.cornerRadius != targetView.layer.cornerRadius { state.cornerRadius = targetView.layer.cornerRadius } if view.layer.shadowColor != targetView.layer.shadowColor { state.shadowColor = targetView.layer.shadowColor } if view.layer.shadowOpacity != targetView.layer.shadowOpacity { state.shadowOpacity = targetView.layer.shadowOpacity } if view.layer.shadowOffset != targetView.layer.shadowOffset { state.shadowOffset = targetView.layer.shadowOffset } if view.layer.shadowRadius != targetView.layer.shadowRadius { state.shadowRadius = targetView.layer.shadowRadius } if view.layer.shadowPath != targetView.layer.shadowPath { state.shadowPath = targetView.layer.shadowPath } if view.layer.contentsRect != targetView.layer.contentsRect { state.contentsRect = targetView.layer.contentsRect } if view.layer.contentsScale != targetView.layer.contentsScale { state.contentsScale = targetView.layer.contentsScale } if view.layer.anchorPoint != targetView.layer.anchorPoint { state.anchorPoint = targetView.layer.anchorPoint } context[view] = state } } #endif ================================================ FILE: Sources/SwiftSupport.swift ================================================ // // SwiftSupport.swift // Hero // // Created by Steven Deutsch on 10/14/18. // Copyright © 2018 Luke Zhao. All rights reserved. // #if canImport(UIKit) && !(swift(>=4.2)) import Foundation import CoreMedia import CoreGraphics extension CMTime { static let zero = kCMTimeZero } enum CAMediaTimingFillMode { static let both = kCAFillModeBoth } enum CAMediaTimingFunctionName { static let linear = kCAMediaTimingFunctionLinear static let easeIn = kCAMediaTimingFunctionEaseIn static let easeOut = kCAMediaTimingFunctionEaseOut static let easeInEaseOut = kCAMediaTimingFunctionEaseInEaseOut } #if canImport(UIKit) import UIKit extension UIControl { typealias State = UIControlState } public extension UINavigationController { typealias Operation = UINavigationControllerOperation } extension UIViewController { var children: [UIViewController] { return childViewControllers } } #endif extension RunLoop { enum Mode { static let common = RunLoopMode.commonModes } } #endif ================================================ FILE: Sources/Transition/HeroProgressRunner.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import QuartzCore protocol HeroProgressRunnerDelegate: AnyObject { func updateProgress(progress: Double) func complete(finished: Bool) } class HeroProgressRunner { weak var delegate: HeroProgressRunnerDelegate? var isRunning: Bool { return displayLink != nil } internal var timePassed: TimeInterval = 0.0 internal var duration: TimeInterval = 0.0 internal var isReversed: Bool = false internal var displayLink: CADisplayLink? @objc func displayUpdate(_ link: CADisplayLink) { timePassed += isReversed ? -link.duration : link.duration if isReversed, timePassed <= 1.0 / 120 { delegate?.complete(finished: false) stop() return } if !isReversed, timePassed > duration - 1.0 / 120 { delegate?.complete(finished: true) stop() return } delegate?.updateProgress(progress: timePassed / duration) } func start(timePassed: TimeInterval, totalTime: TimeInterval, reverse: Bool) { stop() self.timePassed = timePassed self.isReversed = reverse self.duration = totalTime displayLink = CADisplayLink(target: self, selector: #selector(displayUpdate(_:))) displayLink!.add(to: .main, forMode: RunLoop.Mode.common) } func stop() { displayLink?.isPaused = true displayLink?.remove(from: RunLoop.main, forMode: RunLoop.Mode.common) displayLink = nil } } #endif ================================================ FILE: Sources/Transition/HeroTransition+Animate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition { public func animate() { guard state == .starting else { return } state = .animating if let toView = toView { context.unhide(view: toView) } // auto hide all animated views for view in animatingFromViews { context.hide(view: view) } for view in animatingToViews { context.hide(view: view) } var totalDuration: TimeInterval = 0 var animatorWantsInteractive = false if context.insertToViewFirst { for v in animatingToViews { _ = context.snapshotView(for: v) } for v in animatingFromViews { _ = context.snapshotView(for: v) } } else { for v in animatingFromViews { _ = context.snapshotView(for: v) } for v in animatingToViews { _ = context.snapshotView(for: v) } } // UIKit appears to set fromView setNeedLayout to be true. // We don't want fromView to layout after our animation starts. // Therefore we kick off the layout beforehand fromView?.layoutIfNeeded() for animator in animators { let duration = animator.animate(fromViews: animatingFromViews.filter({ animator.canAnimate(view: $0, appearing: false) }), toViews: animatingToViews.filter({ animator.canAnimate(view: $0, appearing: true) })) if duration == .infinity { animatorWantsInteractive = true } else { totalDuration = max(totalDuration, duration) } } self.totalDuration = totalDuration if let forceFinishing = forceFinishing { complete(finished: forceFinishing) } else if let startingProgress = startingProgress { update(startingProgress) } else if animatorWantsInteractive { update(0) } else { complete(after: totalDuration, finishing: true) } fullScreenSnapshot?.removeFromSuperview() } } #endif ================================================ FILE: Sources/Transition/HeroTransition+Complete.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition { public func complete(finished: Bool) { if state == .notified { forceFinishing = finished } guard state == .animating || state == .starting else { return } defer { transitionContext = nil fromViewController = nil toViewController = nil inNavigationController = false inTabBarController = false forceNotInteractive = false animatingToViews.removeAll() animatingFromViews.removeAll() progressUpdateObservers = nil transitionContainer = nil completionCallback = nil forceFinishing = nil container = nil startingProgress = nil processors.removeAll() animators.removeAll() plugins.removeAll() context = nil progress = 0 totalDuration = 0 state = .possible } state = .completing progressRunner.stop() context.clean() if let toView = toView, let fromView = fromView { if finished && isPresenting && toOverFullScreen { // finished presenting a overFullScreen VC context.unhide(rootView: toView) context.removeSnapshots(rootView: toView) context.storeViewAlpha(rootView: fromView) fromViewController?.hero.storedSnapshot = container container.superview?.addSubview(fromView) fromView.addSubview(container) } else if !finished && !isPresenting && fromOverFullScreen { // cancelled dismissing a overFullScreen VC context.unhide(rootView: fromView) context.removeSnapshots(rootView: fromView) context.storeViewAlpha(rootView: toView) toViewController?.hero.storedSnapshot = container container.superview?.addSubview(toView) toView.addSubview(container) } else { context.unhideAll() context.removeAllSnapshots() } // move fromView & toView back from our container back to the one supplied by UIKit if (toOverFullScreen && finished) || (fromOverFullScreen && !finished) { transitionContainer?.addSubview(finished ? fromView : toView) } transitionContainer?.addSubview(finished ? toView : fromView) if isPresenting != finished, !inContainerController, transitionContext != nil { // only happens when present a .overFullScreen VC // bug: http://openradar.appspot.com/radar?id=5320103646199808 // $workaround(eric): try to restore the view of the prensenting view controller to // where it was otherwise. Simply putting the view back under window will leak the view in // some edge cases, for example, when the presenting view was deeply nested under some // exotic view hierarchy (e.g., react native views). as stated where the transition starts, // `originalSuperview` remembers the original super view when the `presenting` transition // animation starts, now it's safe to restore it where it was if possible. if let superview = originalSuperview, superview.window != nil { let view = isPresenting ? fromView : toView superview.addSubview(view) if let frame = originalFrame { view.frame = frame } } else { container.window?.addSubview(isPresenting ? fromView : toView) } } } // clear temporary states only when dismissing finishes. if !isPresenting && finished { originalSuperview = nil originalFrame = nil originalFrameInContainer = nil } if container.superview == transitionContainer { container.removeFromSuperview() } for animator in animators { animator.clean() } transitionContainer?.isUserInteractionEnabled = true completionCallback?(finished) // https://github.com/lkzhao/Hero/issues/354 // tabbar not responding after pushing a view controller with hideBottomBarWhenPushed // this is due to iOS adding a few extra animation to the tabbar but they are not removed when // the transition completes. Possibly another iOS bug. let me know if you have better work around. if finished { toViewController?.tabBarController?.tabBar.layer.removeAllAnimations() } else { fromViewController?.tabBarController?.tabBar.layer.removeAllAnimations() } if finished { if let fvc = fromViewController, let tvc = toViewController { closureProcessForHeroDelegate(vc: fvc) { $0.heroDidEndAnimatingTo?(viewController: tvc) $0.heroDidEndTransition?() } closureProcessForHeroDelegate(vc: tvc) { $0.heroDidEndAnimatingFrom?(viewController: fvc) $0.heroDidEndTransition?() } } transitionContext?.finishInteractiveTransition() } else { if let fvc = fromViewController, let tvc = toViewController { closureProcessForHeroDelegate(vc: fvc) { $0.heroDidCancelAnimatingTo?(viewController: tvc) $0.heroDidCancelTransition?() } closureProcessForHeroDelegate(vc: tvc) { $0.heroDidCancelAnimatingFrom?(viewController: fvc) $0.heroDidCancelTransition?() } } transitionContext?.cancelInteractiveTransition() } transitionContext?.completeTransition(finished) } } #endif ================================================ FILE: Sources/Transition/HeroTransition+CustomTransition.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit // custom transition helper, used in hero_replaceViewController public extension HeroTransition { func transition(from: UIViewController, to: UIViewController, in view: UIView, completion: ((Bool) -> Void)? = nil) { guard !isTransitioning else { return } self.state = .notified isPresenting = true transitionContainer = view fromViewController = from toViewController = to completionCallback = { completion?($0) self.state = .possible } start() } } #endif ================================================ FILE: Sources/Transition/HeroTransition+Interactive.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition { /** Update the progress for the interactive transition. - Parameters: - progress: the current progress, must be between 0...1 */ public func update(_ percentageComplete: CGFloat) { guard state == .animating else { startingProgress = percentageComplete return } self.progressRunner.stop() self.progress = Double(percentageComplete.clamp(0, 1)) } /** Finish the interactive transition. Will stop the interactive transition and animate from the current state to the **end** state */ public func finish(animate: Bool = true) { guard state == .animating || state == .notified || state == .starting else { return } if !animate { self.complete(finished: true) return } var maxTime: TimeInterval = 0 for animator in self.animators { maxTime = max(maxTime, animator.resume(timePassed: self.progress * self.totalDuration, reverse: false)) } self.complete(after: maxTime, finishing: true) } /** Cancel the interactive transition. Will stop the interactive transition and animate from the current state to the **beginning** state */ public func cancel(animate: Bool = true) { guard state == .animating || state == .notified || state == .starting else { return } if !animate { self.complete(finished: false) return } var maxTime: TimeInterval = 0 for animator in self.animators { var adjustedProgress = self.progress if adjustedProgress < 0 { adjustedProgress = -adjustedProgress } maxTime = max(maxTime, animator.resume(timePassed: adjustedProgress * self.totalDuration, reverse: true)) } self.complete(after: maxTime, finishing: false) } /** Override modifiers during an interactive animation. For example: Hero.shared.apply([.position(x:50, y:50)], to:view) will set the view's position to 50, 50 - Parameters: - modifiers: the modifiers to override - view: the view to override to */ public func apply(modifiers: [HeroModifier], to view: UIView) { guard state == .animating else { return } let targetState = HeroTargetState(modifiers: modifiers) if let otherView = self.context.pairedView(for: view) { for animator in self.animators { animator.apply(state: targetState, to: otherView) } } for animator in self.animators { animator.apply(state: targetState, to: view) } } /** Override target state during an interactive animation. For example: Hero.shared.changeTarget([.position(x:50, y:50)], to:view) will animate the view's position to 50, 50 once `finish(animate:)` is called - Parameters: - modifiers: the modifiers to override - isDestination: if false, it changes the starting state - view: the view to override to */ public func changeTarget(modifiers: [HeroModifier], isDestination: Bool = true, to view: UIView) { guard state == .animating else { return } let targetState = HeroTargetState(modifiers: modifiers) if let otherView = self.context.pairedView(for: view) { for animator in self.animators { animator.changeTarget(state: targetState, isDestination: !isDestination, to: otherView) } } for animator in self.animators { animator.changeTarget(state: targetState, isDestination: isDestination, to: view) } } } #endif ================================================ FILE: Sources/Transition/HeroTransition+Start.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition { public func start() { guard state == .notified else { return } state = .starting if let toView = toView, let fromView = fromView { // remember the superview of the view of the `fromViewController` which is // presenting the `toViewController` with `overFullscreen` `modalPresentationStyle`, // so that we can restore the presenting view controller's view later on dismiss if isPresenting && !inContainerController { originalSuperview = fromView.superview originalFrame = fromView.frame } if let toViewController = toViewController, let transitionContext = transitionContext { toView.frame = transitionContext.finalFrame(for: toViewController) } else { toView.frame = fromView.frame } toView.setNeedsLayout() if nil != toView.window { toView.layoutIfNeeded() } } if let fvc = fromViewController, let tvc = toViewController { closureProcessForHeroDelegate(vc: fvc) { $0.heroWillStartTransition?() $0.heroWillStartAnimatingTo?(viewController: tvc) } closureProcessForHeroDelegate(vc: tvc) { $0.heroWillStartTransition?() $0.heroWillStartAnimatingFrom?(viewController: fvc) } } // take a snapshot to hide all the flashing that might happen fullScreenSnapshot = transitionContainer?.window?.snapshotView(afterScreenUpdates: false) ?? fromView?.snapshotView(afterScreenUpdates: false) if let fullScreenSnapshot = fullScreenSnapshot { (transitionContainer?.window ?? transitionContainer)?.addSubview(fullScreenSnapshot) } if let oldSnapshot = fromViewController?.hero.storedSnapshot { oldSnapshot.removeFromSuperview() fromViewController?.hero.storedSnapshot = nil } if let oldSnapshot = toViewController?.hero.storedSnapshot { oldSnapshot.removeFromSuperview() toViewController?.hero.storedSnapshot = nil } plugins = HeroTransition.enabledPlugins.map({ return $0.init() }) processors = [ IgnoreSubviewModifiersPreprocessor(), ConditionalPreprocessor(), DefaultAnimationPreprocessor(), MatchPreprocessor(), SourcePreprocessor(), CascadePreprocessor() ] animators = [ HeroDefaultAnimator() ] if #available(iOS 10, tvOS 10, *) { animators.append(HeroDefaultAnimator()) } // There is no covariant in Swift, so we need to add plugins one by one. plugins.forEach { processors.append($0) animators.append($0) } transitionContainer?.isUserInteractionEnabled = isUserInteractionEnabled // a view to hold all the animating views container = UIView(frame: transitionContainer?.bounds ?? .zero) container.isUserInteractionEnabled = false if !toOverFullScreen && !fromOverFullScreen { container.backgroundColor = containerColor } transitionContainer?.addSubview(container) context = HeroContext(container: container) processors.forEach { $0.hero = self } animators.forEach { $0.hero = self } if let toView = toView, let fromView = fromView, toView != fromView { // if we're presenting a view controller, remember the position & dimension // of the view relative to the transition container so that we can: // - correctly place the view in the transition container when presenting // - correctly place the view back to where it was when dismissing if isPresenting && !inContainerController { originalFrameInContainer = fromView.superview?.convert( fromView.frame, to: container ) } // when dismiss and before animating, place the `toView` to be animated // with the correct position and dimension in the transition container. // otherwise, there will be an apparent visual jagging when the animation begins. if !isPresenting, let frame = originalFrameInContainer { toView.frame = frame } context.loadViewAlpha(rootView: toView) context.loadViewAlpha(rootView: fromView) container.addSubview(toView) container.addSubview(fromView) // when present and before animating, place the `fromView` to be animated // with the correct position and dimension in the transition container to // prevent any possible visual jagging when animation starts, even though not // that apparent in some cases. if isPresenting, let frame = originalFrameInContainer { fromView.frame = frame } toView.updateConstraints() toView.setNeedsLayout() toView.layoutIfNeeded() context.set(fromViews: fromView.flattenedViewHierarchy, toViews: toView.flattenedViewHierarchy) } if (viewOrderingStrategy == .auto && !isPresenting && !inTabBarController) || viewOrderingStrategy == .sourceViewOnTop { context.insertToViewFirst = true } processors.forEach { $0.process(fromViews: context.fromViews, toViews: context.toViews) } animatingFromViews = context.fromViews.filter { (view: UIView) -> Bool in animators.contains { $0.canAnimate(view: view, appearing: false) } } animatingToViews = context.toViews.filter { (view: UIView) -> Bool in animators.contains { $0.canAnimate(view: view, appearing: true) } } if let toView = toView { context.hide(view: toView) } #if os(tvOS) animate() #else if inNavigationController { // When animating within navigationController, we have to dispatch later into the main queue. // otherwise snapshots will be pure white. Possibly a bug with UIKit DispatchQueue.main.async { self.animate() } } else { animate() } #endif } } #endif ================================================ FILE: Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition: UINavigationControllerDelegate { public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { if let previousNavigationDelegate = navigationController.previousNavigationDelegate { previousNavigationDelegate.navigationController?(navigationController, willShow: viewController, animated: animated) } } public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { if let previousNavigationDelegate = navigationController.previousNavigationDelegate { previousNavigationDelegate.navigationController?(navigationController, didShow: viewController, animated: animated) } } public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { guard !isTransitioning else { return nil } self.state = .notified self.isPresenting = operation == .push self.fromViewController = fromViewController ?? fromVC self.toViewController = toViewController ?? toVC self.inNavigationController = true return self } public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return interactiveTransitioning } } #endif ================================================ FILE: Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition: UITabBarControllerDelegate { public func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { guard tabBarController.selectedViewController !== viewController else { return false } if isTransitioning { cancel(animate: false) } return true } #if !os(visionOS) public func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return interactiveTransitioning } public func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { guard !isTransitioning else { return nil } self.state = .notified let fromVCIndex = tabBarController.children.firstIndex(of: fromVC)! let toVCIndex = tabBarController.children.firstIndex(of: toVC)! self.isPresenting = toVCIndex > fromVCIndex self.fromViewController = fromViewController ?? fromVC self.toViewController = toViewController ?? toVC self.inTabBarController = true return self } #endif } #endif ================================================ FILE: Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit extension HeroTransition: UIViewControllerTransitioningDelegate { var interactiveTransitioning: UIViewControllerInteractiveTransitioning? { return forceNotInteractive ? nil : self } public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { guard !isTransitioning else { return nil } self.state = .notified self.isPresenting = true self.fromViewController = fromViewController ?? presenting self.toViewController = toViewController ?? presented return self } public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { guard !isTransitioning else { return nil } self.state = .notified self.isPresenting = false self.fromViewController = fromViewController ?? dismissed return self } public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return interactiveTransitioning } public func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return interactiveTransitioning } } extension HeroTransition: UIViewControllerAnimatedTransitioning { public func animateTransition(using context: UIViewControllerContextTransitioning) { transitionContext = context fromViewController = fromViewController ?? context.viewController(forKey: .from) toViewController = toViewController ?? context.viewController(forKey: .to) transitionContainer = context.containerView start() } public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.375 // doesn't matter, real duration will be calculated later } public func animationEnded(_ transitionCompleted: Bool) { self.state = .possible } } extension HeroTransition: UIViewControllerInteractiveTransitioning { public var wantsInteractiveStart: Bool { return true } public func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) { animateTransition(using: transitionContext) } } #endif ================================================ FILE: Sources/Transition/HeroTransition.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if canImport(UIKit) import UIKit /** ### The singleton class/object for controlling interactive transitions. ```swift Hero.shared ``` #### Use the following methods for controlling the interactive transition: ```swift func update(progress:Double) func end() func cancel() func apply(modifiers:[HeroModifier], to view:UIView) ``` */ public class Hero: NSObject { /// Shared singleton object for controlling the transition public static var shared = HeroTransition() } public protocol HeroTransitionDelegate: AnyObject { func heroTransition(_ hero: HeroTransition, didUpdate state: HeroTransitionState) func heroTransition(_ hero: HeroTransition, didUpdate progress: Double) } open class HeroTransition: NSObject { public weak var delegate: HeroTransitionDelegate? public var defaultAnimation: HeroDefaultAnimationType = .auto public var containerColor: UIColor = .black public var isUserInteractionEnabled = false public var viewOrderingStrategy: HeroViewOrderingStrategy = .auto public var defaultAnimationDirectionStrategy: HeroDefaultAnimationType.Strategy = .forceLeftToRight public internal(set) var state: HeroTransitionState = .possible { didSet { if state != .notified, state != .starting { beginCallback?(state == .animating) beginCallback = nil } delegate?.heroTransition(self, didUpdate: state) } } public var isTransitioning: Bool { return state != .possible } public internal(set) var isPresenting: Bool = true @available(*, renamed: "isTransitioning") public var transitioning: Bool { return isTransitioning } @available(*, renamed: "isPresenting") public var presenting: Bool { return isPresenting } /// container we created to hold all animating views, will be a subview of the /// transitionContainer when transitioning public internal(set) var container: UIView! /// this is the container supplied by UIKit internal var transitionContainer: UIView? internal var completionCallback: ((Bool) -> Void)? internal var beginCallback: ((Bool) -> Void)? internal var processors: [HeroPreprocessor] = [] internal var animators: [HeroAnimator] = [] internal var plugins: [HeroPlugin] = [] internal var animatingFromViews: [UIView] = [] internal var animatingToViews: [UIView] = [] internal var originalSuperview: UIView? internal var originalFrame: CGRect? internal var originalFrameInContainer: CGRect? internal static var enabledPlugins: [HeroPlugin.Type] = [] /// destination view controller public internal(set) var toViewController: UIViewController? /// source view controller public internal(set) var fromViewController: UIViewController? /// context object holding transition informations public internal(set) var context: HeroContext! /// whether or not we are handling transition interactively public var interactive: Bool { return !progressRunner.isRunning } internal var progressUpdateObservers: [HeroProgressUpdateObserver]? /// max duration needed by the animators public internal(set) var totalDuration: TimeInterval = 0.0 /// progress of the current transition. 0 if no transition is happening public internal(set) var progress: Double = 0 { didSet { if state == .animating { if let progressUpdateObservers = progressUpdateObservers { for observer in progressUpdateObservers { observer.heroDidUpdateProgress(progress: progress) } } let timePassed = progress * totalDuration if interactive { for animator in animators { animator.seekTo(timePassed: timePassed) } } else { for plugin in plugins where plugin.requirePerFrameCallback { plugin.seekTo(timePassed: timePassed) } } transitionContext?.updateInteractiveTransition(CGFloat(progress)) } delegate?.heroTransition(self, didUpdate: progress) } } lazy var progressRunner: HeroProgressRunner = { let runner = HeroProgressRunner() runner.delegate = self return runner }() /// a UIViewControllerContextTransitioning object provided by UIKit, /// might be nil when transitioning. This happens when calling heroReplaceViewController internal weak var transitionContext: UIViewControllerContextTransitioning? internal var fullScreenSnapshot: UIView? // By default, Hero will always appear to be interactive to UIKit. This forces it to appear non-interactive. // Used when doing a hero_replaceViewController within a UINavigationController, to fix a bug with // UINavigationController.setViewControllers not able to handle interactive transition internal var forceNotInteractive = false internal var forceFinishing: Bool? internal var startingProgress: CGFloat? internal var inNavigationController = false internal var inTabBarController = false internal var inContainerController: Bool { return inNavigationController || inTabBarController } internal var toOverFullScreen: Bool { return !inContainerController && (toViewController?.modalPresentationStyle == .overFullScreen || toViewController?.modalPresentationStyle == .overCurrentContext) } internal var fromOverFullScreen: Bool { return !inContainerController && (fromViewController?.modalPresentationStyle == .overFullScreen || fromViewController?.modalPresentationStyle == .overCurrentContext) } internal var toView: UIView? { return toViewController?.view } internal var fromView: UIView? { return fromViewController?.view } public override init() { super.init() } func complete(after: TimeInterval, finishing: Bool) { guard [HeroTransitionState.animating, .starting, .notified].contains(state) else { return } if after <= 1.0 / 120 { complete(finished: finishing) return } let totalTime: TimeInterval if finishing { totalTime = after / max((1 - progress), 0.01) } else { totalTime = after / max(progress, 0.01) } progressRunner.start(timePassed: progress * totalTime, totalTime: totalTime, reverse: !finishing) } // MARK: Observe Progress /** Receive callbacks on each animation frame. Observers will be cleaned when transition completes - Parameters: - observer: the observer */ public func observeForProgressUpdate(observer: HeroProgressUpdateObserver) { if progressUpdateObservers == nil { progressUpdateObservers = [] } progressUpdateObservers!.append(observer) } } extension HeroTransition: HeroProgressRunnerDelegate { func updateProgress(progress: Double) { self.progress = progress } } #endif ================================================ FILE: Sources/Transition/HeroTransitionState.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation public enum HeroTransitionState: Int { // Hero is able to start a new transition case possible // UIKit has notified Hero about a pending transition. // Hero haven't started preparing. case notified // Hero's `start` method has been called. Preparing the animation. case starting // Hero's `animate` method has been called. Animation has started. case animating // Hero's `complete` method has been called. Transition is ended or cancelled. Hero is doing cleanup. case completing } ================================================ FILE: Tests/HeroTests.swift ================================================ // // HeroTests.swift // HeroTests // // Created by Luke Zhao on 2/28/17. // Copyright © 2017 Luke Zhao. All rights reserved. // import XCTest import Hero @discardableResult func parse(_ source: String) throws -> [ExprNode] { let lexer = Lexer(input: source) let tokens = lexer.tokenize() let parser = Parser(tokens: tokens) return try parser.parse() } class HeroTests: XCTestCase { func testNoArg() { XCTAssertEqual(try! parse("fade()"), [CallNode(name: "fade", arguments: [])]) XCTAssertEqual(try! parse("fade"), [VariableNode(name: "fade")]) } func testArg() { XCTAssertEqual(try! parse("fade(123, fade)"), [CallNode(name: "fade", arguments: [NumberNode(value: 123), VariableNode(name: "fade")])]) } func testMultiple() { XCTAssertEqual(try! parse("fade() fade catch catch(123) catch"), [CallNode(name: "fade", arguments: []), VariableNode(name: "fade"), VariableNode(name: "catch"), CallNode(name: "catch", arguments: [NumberNode(value: 123.0)]), VariableNode(name: "catch")]) } func testNested() { XCTAssertEqual(try! parse("fade(fade(catch(123, fade)))"), [CallNode(name: "fade", arguments: [ CallNode(name: "fade", arguments: [ CallNode(name: "catch", arguments: [ NumberNode(value: 123.0), VariableNode(name: "fade")]) ]) ]) ]) } func testError() throws { print(try parse("scale(0.5) translate(200, 0) fade useGlobalCoordinateSpace")) XCTAssertThrowsError(try parse("()"), "") { (error) in if case ParseError.expectExpression = error {} else { XCTFail() } } } } ================================================ FILE: Tests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 ================================================ FILE: TvOSExamples/AppDelegate.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } #if !(swift(>=4.2)) extension UIApplication { typealias LaunchOptionsKey = UIApplicationLaunchOptionsKey } #endif ================================================ FILE: TvOSExamples/Base.lproj/Main.storyboard ================================================ ================================================ FILE: TvOSExamples/Basic.storyboard ================================================ ================================================ FILE: TvOSExamples/ImageGallery.storyboard ================================================ ================================================ FILE: TvOSExamples/ImageViewer.storyboard ================================================ ================================================ FILE: TvOSExamples/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName Hero Examples CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion 1 LSRequiresIPhoneOS UIMainStoryboardFile Main UIRequiredDeviceCapabilities arm64 UIUserInterfaceStyle Dark ================================================ FILE: TvOSExamples/TVImageGalleryViewController.swift ================================================ // The MIT License (MIT) // // Copyright (c) 2016 Luke Zhao // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import UIKit import Hero class TVImageGalleryViewController: ImageGalleryViewController { @IBOutlet weak var topImageView: UIImageView! override func viewDidLoad() { columns = 5 cellSize = CGSize(width: (self.view.bounds.width - CGFloat(self.columns + 1)*64)/CGFloat(self.columns), height: (self.view.bounds.width - CGFloat(self.columns + 1)*64)/CGFloat(self.columns)) super.viewDidLoad() } } ================================================ FILE: book.json ================================================ { "gitbook": "3.2.2", "title": "Hero", "plugins": ["edit-link", "prism", "-highlight", "github", "anchorjs"], "pluginsConfig": { "edit-link": { "base": "https://github.com/lkzhao/Hero/tree/master", "label": "Edit This Page" }, "github": { "url": "https://github.com/lkzhao/Hero/" } } } ================================================ FILE: docs/Classes/BinaryOpNode.html ================================================ BinaryOpNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/CallNode.html ================================================ CallNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/ExprNode.html ================================================ ExprNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/FunctionNode.html ================================================ FunctionNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/Hero.html ================================================ Hero Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/HeroContext.html ================================================ HeroContext Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroContext

public class HeroContext

Undocumented

================================================ FILE: docs/Classes/HeroDebugPlugin.html ================================================ HeroDebugPlugin Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/HeroExtension.html ================================================ HeroExtension Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroExtension

public class HeroExtension<Base>

Undocumented

Available where Base: UIView

  • id

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

    Declaration

    Swift

    var id: String? { get set }
  • isEnabled allows to specify whether a view and its subviews should be consider for animations. If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true

    Declaration

    Swift

    var isEnabled: Bool { get set }
  • isEnabledForSubviews allows to specify whether a view’s subviews should be consider for animations. If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true

    Declaration

    Swift

    var isEnabledForSubviews: Bool { get set }
  • Use modifiers to specify animations alongside the main transition. Checkout HeroModifier.swift for available modifiers.

    Declaration

    Swift

    var modifiers: [HeroModifier]? { get set }
  • modifierString** provides another way to set modifiers. It can be assigned through storyboard.

    Declaration

    Swift

    var modifierString: String? { get set }

Available where Base: UIViewController

Available where Base: UINavigationController

Available where Base: UITabBarController

Available where Base: UIViewController

================================================ FILE: docs/Classes/HeroModifier.html ================================================ HeroModifier Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroModifier

public final class HeroModifier
extension HeroModifier: HeroStringConvertible

Undocumented

  • Undocumented

    Declaration

    Swift

    public init(applyFunction: @escaping (inout HeroTargetState) -> Void)
  • Apply modifiers directly to the view at the start of the transition. The modifiers supplied here won’t be animated. For source views, modifiers are set directly at the beginning of the animation. For destination views, they replace the target state (final appearance).

    Declaration

    Swift

    public static func beginWith(_ modifiers: [HeroModifier]) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func beginWith(modifiers: [HeroModifier]) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func beginWith(_ modifiers: HeroModifier...) -> HeroModifier
  • Use global coordinate space.

    When using global coordinate space. The view become a independent view that is not a subview of any view. It won’t move when its parent view moves, and won’t be affected by parent view’s attributes.

    When a view is matched, this is automatically enabled. The source modifier will also enable this.

    Global coordinate space is default for all views prior to version 0.1.3

    Declaration

    Swift

    public static var useGlobalCoordinateSpace: HeroModifier
  • ignore all heroModifiers attributes for a view’s direct subviews.

    Declaration

    Swift

    public static var ignoreSubviewModifiers: HeroModifier
  • ignore all heroModifiers attributes for a view’s subviews.

    • recursive: if false, will only ignore direct subviews’ modifiers. default false.

    Declaration

    Swift

    public static func ignoreSubviewModifiers(recursive: Bool = false) -> HeroModifier
  • Will create snapshot optimized for different view type. 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.

    This modifier actually does nothing by itself since .useOptimizedSnapshot is the default.

    Declaration

    Swift

    public static var useOptimizedSnapshot: HeroModifier
  • Create snapshot using snapshotView(afterScreenUpdates:).

    Declaration

    Swift

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

    Declaration

    Swift

    public static var useLayerRenderSnapshot: HeroModifier
  • Force Hero to not create any snapshot when animating this view. This will mess up the view hierarchy, therefore, view controllers have to rebuild its view structure after the transition finishes.

    Declaration

    Swift

    public static var useNoSnapshot: HeroModifier
  • Force the view to animate.

    By default, Hero will not animate if the view is outside the screen bounds or if there is no animatable hero modifier, unless this modifier is used.

    Declaration

    Swift

    public static var forceAnimate: HeroModifier
  • 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 performance.

    Declaration

    Swift

    public static var useScaleBasedSizeChange: HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func from(node: ExprNode) -> HeroModifier?
  • Fade the view during transition

    Declaration

    Swift

    public static var fade: HeroModifier
  • Force don’t fade view during transition

    Declaration

    Swift

    public static var forceNonFade: HeroModifier
  • Set the position for the view to animate from/to.

    • position: position for the view to animate from/to

    Declaration

    Swift

    public static func position(_ position: CGPoint) -> HeroModifier
  • Set the size for the view to animate from/to.

    • size: size for the view to animate from/to

    Declaration

    Swift

    public static func size(_ size: CGSize) -> HeroModifier
  • Set the transform for the view to animate from/to. Will override previous perspective, scale, translate, & rotate modifiers

    • t: the CATransform3D object

    Declaration

    Swift

    public static func transform(_ t: CATransform3D) -> HeroModifier
  • Set the perspective on the transform. use in combination with the rotate modifier.

    • perspective: set the camera distance of the transform

    Declaration

    Swift

    public static func perspective(_ perspective: CGFloat) -> HeroModifier
  • Scale 3d

    • x: scale factor on x axis, default 1
    • y: scale factor on y axis, default 1
    • z: scale factor on z axis, default 1

    Declaration

    Swift

    public static func scale(x: CGFloat = 1, y: CGFloat = 1, z: CGFloat = 1) -> HeroModifier
  • Scale in x & y axis

    • xy: scale factor in both x & y axis

    Declaration

    Swift

    public static func scale(_ xy: CGFloat) -> HeroModifier
  • Translate 3d

    • x: translation distance on x axis in display pixel, default 0
    • y: translation distance on y axis in display pixel, default 0
    • z: translation distance on z axis in display pixel, default 0

    Declaration

    Swift

    public static func translate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func translate(_ point: CGPoint, z: CGFloat = 0) -> HeroModifier
  • Rotate 3d

    • x: rotation on x axis in radian, default 0
    • y: rotation on y axis in radian, default 0
    • z: rotation on z axis in radian, default 0

    Declaration

    Swift

    public static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func rotate(_ point: CGPoint, z: CGFloat = 0) -> HeroModifier
  • Rotate 2d

    • z: rotation in radian

    Declaration

    Swift

    public static func rotate(_ z: CGFloat) -> HeroModifier

UIKit

  • Set the backgroundColor for the view to animate from/to.

    • backgroundColor: backgroundColor for the view to animate from/to

    Declaration

    Swift

    public static func backgroundColor(_ backgroundColor: UIColor) -> HeroModifier
  • Set the borderColor for the view to animate from/to.

    • borderColor: borderColor for the view to animate from/to

    Declaration

    Swift

    public static func borderColor(_ borderColor: UIColor) -> HeroModifier
  • Set the shadowColor for the view to animate from/to.

    • shadowColor: shadowColor for the view to animate from/to

    Declaration

    Swift

    public static func shadowColor(_ shadowColor: UIColor) -> HeroModifier
  • Create an overlay on the animating view.

    • color: color of the overlay
    • opacity: opacity of the overlay

    Declaration

    Swift

    public static func overlay(color: UIColor, opacity: CGFloat) -> HeroModifier
  • Set the opacity for the view to animate from/to.

    • opacity: opacity for the view to animate from/to

    Declaration

    Swift

    public static func opacity(_ opacity: CGFloat) -> HeroModifier
  • Set the cornerRadius for the view to animate from/to.

    • cornerRadius: cornerRadius for the view to animate from/to

    Declaration

    Swift

    public static func cornerRadius(_ cornerRadius: CGFloat) -> HeroModifier
  • Set the zPosition for the view to animate from/to.

    • zPosition: zPosition for the view to animate from/to

    Declaration

    Swift

    public static func zPosition(_ zPosition: CGFloat) -> HeroModifier
  • Set the contentsRect for the view to animate from/to.

    • contentsRect: contentsRect for the view to animate from/to

    Declaration

    Swift

    public static func contentsRect(_ contentsRect: CGRect) -> HeroModifier
  • Set the contentsScale for the view to animate from/to.

    • contentsScale: contentsScale for the view to animate from/to

    Declaration

    Swift

    public static func contentsScale(_ contentsScale: CGFloat) -> HeroModifier
  • Set the borderWidth for the view to animate from/to.

    • borderWidth: borderWidth for the view to animate from/to

    Declaration

    Swift

    public static func borderWidth(_ borderWidth: CGFloat) -> HeroModifier
  • Set the shadowOpacity for the view to animate from/to.

    • shadowOpacity: shadowOpacity for the view to animate from/to

    Declaration

    Swift

    public static func shadowOpacity(_ shadowOpacity: CGFloat) -> HeroModifier
  • Set the shadowOffset for the view to animate from/to.

    • shadowOffset: shadowOffset for the view to animate from/to

    Declaration

    Swift

    public static func shadowOffset(_ shadowOffset: CGSize) -> HeroModifier
  • Set the shadowRadius for the view to animate from/to.

    • shadowRadius: shadowRadius for the view to animate from/to

    Declaration

    Swift

    public static func shadowRadius(_ shadowRadius: CGFloat) -> HeroModifier
  • Set the shadowPath for the view to animate from/to.

    • shadowPath: shadowPath for the view to animate from/to

    Declaration

    Swift

    public static func shadowPath(_ shadowPath: CGPath) -> HeroModifier
  • Set the masksToBounds for the view to animate from/to.

    • masksToBounds: masksToBounds for the view to animate from/to

    Declaration

    Swift

    public static func masksToBounds(_ masksToBounds: Bool) -> HeroModifier
  • Sets the duration of the animation for a given view. If not used, Hero will use determine the duration based on the distance and size changes.

    • duration: duration of the animation

    Note: a duration of .infinity means matching the duration of the longest animation. same as .durationMatchLongest

    Declaration

    Swift

    public static func duration(_ duration: TimeInterval) -> HeroModifier
  • Sets the duration of the animation for a given view to match the longest animation of the transition.

    Declaration

    Swift

    public static var durationMatchLongest: HeroModifier
  • Sets the delay of the animation for a given view.

    • delay: delay of the animation

    Declaration

    Swift

    public static func delay(_ delay: TimeInterval) -> HeroModifier
  • Sets the timing function of the animation for a given view. If not used, Hero will use determine the timing function based on whether or not the view is entering or exiting the screen.

    • timingFunction: timing function of the animation

    Declaration

    Swift

    public static func timingFunction(_ timingFunction: CAMediaTimingFunction) -> HeroModifier
  • (iOS 9+) Use spring animation with custom stiffness & damping. The duration will be automatically calculated. Will be ignored if arc, timingFunction, or duration is set.

    • stiffness: stiffness of the spring
    • damping: damping of the spring

    Declaration

    Swift

    @available(iOS 9, *)
    public static func spring(stiffness: CGFloat, damping: CGFloat) -> HeroModifier
  • Transition from/to the state of the view with matching heroID Will also force the view to use global coordinate space.

    The following layer properties will be animated from the given view.

    position bounds.size cornerRadius transform shadowColor shadowOpacity shadowOffset shadowRadius shadowPath

    Note that the following properties won’t be taken from the source view.

    backgroundColor borderWidth borderColor

    • heroID: the source view’s heroId.

    Declaration

    Swift

    public static func source(heroID: String) -> HeroModifier
  • arc

    Works in combination with position modifier to apply a natural curve when moving to the destination.

    Declaration

    Swift

    public static var arc: HeroModifier
  • Works in combination with position modifier to apply a natural curve when moving to the destination.

    • intensity: a value of 1 represent a downward natural curve ╰. a value of -1 represent a upward curve ╮. default is 1.

    Declaration

    Swift

    public static func arc(intensity: CGFloat = 1) -> HeroModifier
  • Cascade applys increasing delay modifiers to subviews

    Declaration

    Swift

    public static var cascade: HeroModifier
  • Cascade applys increasing delay modifiers to subviews

    • delta: delay in between each animation
    • direction: cascade direction
    • delayMatchedViews: whether or not to delay matched subviews until all cascading animation have started

    Declaration

    Swift

    public static func cascade(delta: TimeInterval = 0.02,
                               direction: CascadeDirection = .topToBottom,
                               delayMatchedViews: Bool = false) -> HeroModifier
  • Apply modifiers only if the condition return true.

    Declaration

    Swift

    public static func when(_ condition: @escaping (HeroConditionalContext) -> Bool, _ modifiers: [HeroModifier]) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func when(_ condition: @escaping (HeroConditionalContext) -> Bool, _ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenMatched(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenPresenting(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenDismissing(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenAppearing(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenDisappearing(_ modifiers: HeroModifier...) -> HeroModifier
================================================ FILE: docs/Classes/HeroPlugin.html ================================================ HeroPlugin Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroPlugin

open class HeroPlugin : NSObject, HeroPreprocessor, HeroAnimator

Undocumented

  • Undocumented

    Declaration

    Swift

    weak public var hero: HeroTransition!
  • Undocumented

    Declaration

    Swift

    public var context: HeroContext! { get }
  • Determines whether or not to receive seekTo callback on every frame.

    Default is false.

    When requirePerFrameCallback is false, the plugin needs to start its own animations inside animate & resume The seekTo method is only being called during an interactive transition.

    When requirePerFrameCallback is true, the plugin will receive seekTo callback on every animation frame. Hence it is possible for the plugin to do per-frame animations without implementing animate & resume

    Declaration

    Swift

    open var requirePerFrameCallback: Bool
  • Undocumented

    Declaration

    Swift

    public override required init()
  • Called before any animation. Override this method when you want to preprocess modifiers for views

    To check a view’s modifiers:

    context[view]
    context[view, "modifierName"]
    

    To set a view’s modifiers:

    context[view] = [("modifier1", ["parameter1"]), ("modifier2", [])]
    context[view, "modifier1"] = ["parameter1", "parameter2"]
    

    Declaration

    Swift

    open func process(fromViews: [UIView], toViews: [UIView])

    Parameters

    context

    object holding all parsed and changed modifiers,

    fromViews

    A flattened list of all views from source ViewController

    toViews

    A flattened list of all views from destination ViewController

  • Declaration

    Swift

    open func canAnimate(view: UIView, appearing: Bool) -> Bool

    Parameters

    context

    object holding all parsed and changed modifiers,

    view

    the view to check whether or not the plugin can handle the animation

    appearing

    true if the view is appearing(i.e. a view in destination ViewController) If return true, Hero won’t animate and won’t let any other plugins animate this view. The view will also be hidden automatically during the animation.

    Return Value

    return true if the plugin can handle animating the view.

  • Perform the animation.

    Note: views in fromViews & toViews are hidden already. Unhide then if you need to take snapshots.

    Declaration

    Swift

    open func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval

    Parameters

    context

    object holding all parsed and changed modifiers,

    fromViews

    A flattened list of all views from source ViewController (filtered by canAnimate)

    toViews

    A flattened list of all views from destination ViewController (filtered by canAnimate)

    Return Value

    The duration needed to complete the animation

  • Called when all animations are completed.

    Should perform cleanup and release any reference

    Declaration

    Swift

    open func clean()
  • For supporting interactive animation only.

    This method is called when an interactive animation is in place The plugin should pause the animation, and seek to the given progress

    Declaration

    Swift

    open func seekTo(timePassed: TimeInterval)

    Parameters

    timePassed

    time of the animation to seek to.

  • For supporting interactive animation only.

    This method is called when an interactive animation is ended The plugin should resume the animation.

    • timePassed: will be the same value since last seekTo
    • reverse: a boolean value indicating whether or not the animation should reverse

    Declaration

    Swift

    open func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval
  • For supporting interactive animation only.

    This method is called when user wants to override animation modifiers during an interactive animation

    Declaration

    Swift

    open func apply(state: HeroTargetState, to view: UIView)

    Parameters

    state

    the target state to override

    view

    the view to override

  • Undocumented

    Declaration

    Swift

    open func changeTarget(state: HeroTargetState, isDestination: Bool, to view: UIView)
  • Undocumented

    Declaration

    Swift

    public static var isEnabled: Bool { get set }
  • Undocumented

    Declaration

    Swift

    public static func enable()
  • Undocumented

    Declaration

    Swift

    public static func disable()
================================================ FILE: docs/Classes/HeroTransition.html ================================================ HeroTransition Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroTransition

open class HeroTransition : NSObject
extension HeroTransition: UINavigationControllerDelegate
extension HeroTransition: UITabBarControllerDelegate
extension HeroTransition: UIViewControllerTransitioningDelegate
extension HeroTransition: UIViewControllerAnimatedTransitioning
extension HeroTransition: UIViewControllerInteractiveTransitioning

Undocumented

Observe Progress

================================================ FILE: docs/Classes/Lexer.html ================================================ Lexer Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/NumberNode.html ================================================ NumberNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/Parser.html ================================================ Parser Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/PrototypeNode.html ================================================ PrototypeNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes/VariableNode.html ================================================ VariableNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Classes.html ================================================ Classes Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Classes

The following classes are available globally.

================================================ FILE: docs/Enums/CascadeDirection.html ================================================ CascadeDirection Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

CascadeDirection

public enum CascadeDirection

Undocumented

================================================ FILE: docs/Enums/HeroCoordinateSpace.html ================================================ HeroCoordinateSpace Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Enums/HeroDefaultAnimationType/Direction.html ================================================ Direction Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Direction

public enum Direction : HeroStringConvertible

Undocumented

================================================ FILE: docs/Enums/HeroDefaultAnimationType/Strategy.html ================================================ Strategy Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Enums/HeroDefaultAnimationType.html ================================================ HeroDefaultAnimationType Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroDefaultAnimationType

public enum HeroDefaultAnimationType
extension HeroDefaultAnimationType: HeroStringConvertible

Undocumented

================================================ FILE: docs/Enums/HeroSnapshotType.html ================================================ HeroSnapshotType Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroSnapshotType

public enum HeroSnapshotType

Undocumented

  • Will optimize for different type of views For custom views or views with masking, .optimizedDefault might create snapshots that appear differently than the actual view. In that case, use .normal or .slowRender to disable the optimization

    Declaration

    Swift

    case optimized
  • snapshotView(afterScreenUpdates:)

    Declaration

    Swift

    case normal
  • layer.render(in: currentContext)

    Declaration

    Swift

    case layerRender
  • will not create snapshot. animate the view directly. This will mess up the view hierarchy, therefore, view controllers have to rebuild its view structure after the transition finishes

    Declaration

    Swift

    case noSnapshot
================================================ FILE: docs/Enums/HeroTransitionState.html ================================================ HeroTransitionState Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Enums/HeroViewOrderingStrategy.html ================================================ HeroViewOrderingStrategy Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Enums/ParseError.html ================================================ ParseError Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Enums/Token.html ================================================ Token Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Enums.html ================================================ Enumerations Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Enumerations

The following enumerations are available globally.

================================================ FILE: docs/Extensions/CAMediaTimingFunction.html ================================================ CAMediaTimingFunction Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

CAMediaTimingFunction

public extension CAMediaTimingFunction
================================================ FILE: docs/Extensions/CATransform3D.html ================================================ CATransform3D Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Extensions/HeroDebugView.html ================================================ HeroDebugView Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Extensions/String.html ================================================ String Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Extensions/UINavigationController.html ================================================ UINavigationController Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Extensions/UITabBarController.html ================================================ UITabBarController Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Extensions/UIView.html ================================================ UIView Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Extensions/UIViewController.html ================================================ UIViewController Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

UIViewController

extension UIViewController: HeroCompatible
================================================ FILE: docs/Extensions.html ================================================ Extensions Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Functions.html ================================================ Functions Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroAnimator.html ================================================ HeroAnimator Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroAnimator

public protocol HeroAnimator : AnyObject

Undocumented

================================================ FILE: docs/Protocols/HeroCompatible.html ================================================ HeroCompatible Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroCustomSnapshotView.html ================================================ HeroCustomSnapshotView Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroPreprocessor.html ================================================ HeroPreprocessor Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroProgressUpdateObserver.html ================================================ HeroProgressUpdateObserver Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroStringConvertible.html ================================================ HeroStringConvertible Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroTransitionDelegate.html ================================================ HeroTransitionDelegate Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/Protocols/HeroViewControllerDelegate.html ================================================ HeroViewControllerDelegate Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroViewControllerDelegate

@objc
public protocol HeroViewControllerDelegate

Undocumented

================================================ FILE: docs/Protocols.html ================================================ Protocols Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Protocols

The following protocols are available globally.

================================================ FILE: docs/Structs/HeroConditionalContext.html ================================================ HeroConditionalContext Structure Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroConditionalContext

public struct HeroConditionalContext

Undocumented

================================================ FILE: docs/Structs/HeroTargetState.html ================================================ HeroTargetState Structure Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroTargetState

public struct HeroTargetState
extension HeroTargetState: ExpressibleByArrayLiteral

Undocumented

================================================ FILE: docs/Structs.html ================================================ Structures Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/css/highlight.css ================================================ /*! Jazzy - https://github.com/realm/jazzy * Copyright Realm Inc. * SPDX-License-Identifier: MIT */ /* Credit to https://gist.github.com/wataru420/2048287 */ .highlight .c { color: #999988; font-style: italic; } .highlight .err { color: #a61717; background-color: #e3d2d2; } .highlight .k { color: #000000; font-weight: bold; } .highlight .o { color: #000000; font-weight: bold; } .highlight .cm { color: #999988; font-style: italic; } .highlight .cp { color: #999999; font-weight: bold; } .highlight .c1 { color: #999988; font-style: italic; } .highlight .cs { color: #999999; font-weight: bold; font-style: italic; } .highlight .gd { color: #000000; background-color: #ffdddd; } .highlight .gd .x { color: #000000; background-color: #ffaaaa; } .highlight .ge { color: #000000; font-style: italic; } .highlight .gr { color: #aa0000; } .highlight .gh { color: #999999; } .highlight .gi { color: #000000; background-color: #ddffdd; } .highlight .gi .x { color: #000000; background-color: #aaffaa; } .highlight .go { color: #888888; } .highlight .gp { color: #555555; } .highlight .gs { font-weight: bold; } .highlight .gu { color: #aaaaaa; } .highlight .gt { color: #aa0000; } .highlight .kc { color: #000000; font-weight: bold; } .highlight .kd { color: #000000; font-weight: bold; } .highlight .kp { color: #000000; font-weight: bold; } .highlight .kr { color: #000000; font-weight: bold; } .highlight .kt { color: #445588; } .highlight .m { color: #009999; } .highlight .s { color: #d14; } .highlight .na { color: #008080; } .highlight .nb { color: #0086B3; } .highlight .nc { color: #445588; font-weight: bold; } .highlight .no { color: #008080; } .highlight .ni { color: #800080; } .highlight .ne { color: #990000; font-weight: bold; } .highlight .nf { color: #990000; } .highlight .nn { color: #555555; } .highlight .nt { color: #000080; } .highlight .nv { color: #008080; } .highlight .ow { color: #000000; font-weight: bold; } .highlight .w { color: #bbbbbb; } .highlight .mf { color: #009999; } .highlight .mh { color: #009999; } .highlight .mi { color: #009999; } .highlight .mo { color: #009999; } .highlight .sb { color: #d14; } .highlight .sc { color: #d14; } .highlight .sd { color: #d14; } .highlight .s2 { color: #d14; } .highlight .se { color: #d14; } .highlight .sh { color: #d14; } .highlight .si { color: #d14; } .highlight .sx { color: #d14; } .highlight .sr { color: #009926; } .highlight .s1 { color: #d14; } .highlight .ss { color: #990073; } .highlight .bp { color: #999999; } .highlight .vc { color: #008080; } .highlight .vg { color: #008080; } .highlight .vi { color: #008080; } .highlight .il { color: #009999; } ================================================ FILE: docs/css/jazzy.css ================================================ /*! Jazzy - https://github.com/realm/jazzy * Copyright Realm Inc. * SPDX-License-Identifier: MIT */ *, *:before, *:after { box-sizing: inherit; } body { margin: 0; background: #fff; color: #333; font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; letter-spacing: .2px; -webkit-font-smoothing: antialiased; box-sizing: border-box; } h1 { font-size: 2rem; font-weight: 700; margin: 1.275em 0 0.6em; } h2 { font-size: 1.75rem; font-weight: 700; margin: 1.275em 0 0.3em; } h3 { font-size: 1.5rem; font-weight: 700; margin: 1em 0 0.3em; } h4 { font-size: 1.25rem; font-weight: 700; margin: 1.275em 0 0.85em; } h5 { font-size: 1rem; font-weight: 700; margin: 1.275em 0 0.85em; } h6 { font-size: 1rem; font-weight: 700; margin: 1.275em 0 0.85em; color: #777; } p { margin: 0 0 1em; } ul, ol { padding: 0 0 0 2em; margin: 0 0 0.85em; } blockquote { margin: 0 0 0.85em; padding: 0 15px; color: #858585; border-left: 4px solid #e5e5e5; } img { max-width: 100%; } a { color: #4183c4; text-decoration: none; } a:hover, a:focus { outline: 0; text-decoration: underline; } a.discouraged { text-decoration: line-through; } a.discouraged:hover, a.discouraged:focus { text-decoration: underline line-through; } table { background: #fff; width: 100%; border-collapse: collapse; border-spacing: 0; overflow: auto; margin: 0 0 0.85em; } tr:nth-child(2n) { background-color: #fbfbfb; } th, td { padding: 6px 13px; border: 1px solid #ddd; } hr { height: 1px; border: none; background-color: #ddd; } pre { margin: 0 0 1.275em; padding: .85em 1em; overflow: auto; background: #f7f7f7; font-size: .85em; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } code { font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } .item-container p > code, .item-container li > code, .top-matter p > code, .top-matter li > code { background: #f7f7f7; padding: .2em; } .item-container p > code:before, .item-container p > code:after, .item-container li > code:before, .item-container li > code:after, .top-matter p > code:before, .top-matter p > code:after, .top-matter li > code:before, .top-matter li > code:after { letter-spacing: -.2em; content: "\00a0"; } pre code { padding: 0; white-space: pre; } .content-wrapper { display: flex; flex-direction: column; } @media (min-width: 768px) { .content-wrapper { flex-direction: row; } } .header { display: flex; padding: 8px; font-size: 0.875em; background: #444; color: #999; } .header-col { margin: 0; padding: 0 8px; } .header-col--primary { flex: 1; } .header-link { color: #fff; } .header-icon { padding-right: 2px; vertical-align: -3px; height: 16px; } .breadcrumbs { font-size: 0.875em; padding: 8px 16px; margin: 0; background: #fbfbfb; border-bottom: 1px solid #ddd; } .carat { height: 10px; margin: 0 5px; } .navigation { order: 2; } @media (min-width: 768px) { .navigation { order: 1; width: 25%; max-width: 300px; padding-bottom: 64px; overflow: hidden; word-wrap: normal; background: #fbfbfb; border-right: 1px solid #ddd; } } .nav-groups { list-style-type: none; padding-left: 0; } .nav-group-name { border-bottom: 1px solid #ddd; padding: 8px 0 8px 16px; } .nav-group-name-link { color: #333; } .nav-group-tasks { margin: 8px 0; padding: 0 0 0 8px; } .nav-group-task { font-size: 1em; list-style-type: none; white-space: nowrap; } .nav-group-task-link { color: #808080; } .main-content { order: 1; } @media (min-width: 768px) { .main-content { order: 2; flex: 1; padding-bottom: 60px; } } .section { padding: 0 32px; border-bottom: 1px solid #ddd; } .section-content { max-width: 834px; margin: 0 auto; padding: 16px 0; } .section-name { color: #666; display: block; } .section-name p { margin-bottom: inherit; } .declaration .highlight { overflow-x: initial; padding: 8px 0; margin: 0; background-color: transparent; border: none; } .task-group-section { border-top: 1px solid #ddd; } .task-group { padding-top: 0px; } .task-name-container a[name]:before { content: ""; display: block; } .section-name-container { position: relative; } .section-name-container .section-name-link { position: absolute; top: 0; left: 0; bottom: 0; right: 0; margin-bottom: 0; } .section-name-container .section-name { position: relative; pointer-events: none; z-index: 1; } .section-name-container .section-name a { pointer-events: auto; } .item-container { padding: 0; } .item { padding-top: 8px; width: 100%; list-style-type: none; } .item a[name]:before { content: ""; display: block; } .item .token, .item .direct-link { display: inline-block; text-indent: -20px; padding-left: 3px; margin-left: 20px; font-size: 1rem; } .item .declaration-note { font-size: .85em; color: #808080; font-style: italic; } .pointer-container { border-bottom: 1px solid #ddd; left: -23px; padding-bottom: 13px; position: relative; width: 110%; } .pointer { left: 21px; top: 7px; display: block; position: absolute; width: 12px; height: 12px; border-left: 1px solid #ddd; border-top: 1px solid #ddd; background: #fff; transform: rotate(45deg); } .height-container { display: none; position: relative; width: 100%; overflow: hidden; } .height-container .section { background: #fff; border: 1px solid #ddd; border-top-width: 0; padding-top: 10px; padding-bottom: 5px; padding: 8px 16px; } .aside, .language { padding: 6px 12px; margin: 12px 0; border-left: 5px solid #dddddd; overflow-y: hidden; } .aside .aside-title, .language .aside-title { font-size: 9px; letter-spacing: 2px; text-transform: uppercase; padding-bottom: 0; margin: 0; color: #aaa; -webkit-user-select: none; } .aside p:last-child, .language p:last-child { margin-bottom: 0; } .language { border-left: 5px solid #cde9f4; } .language .aside-title { color: #4183c4; } .aside-warning, .aside-deprecated, .aside-unavailable { border-left: 5px solid #ff6666; } .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { color: #ff0000; } .graybox { border-collapse: collapse; width: 100%; } .graybox p { margin: 0; word-break: break-word; min-width: 50px; } .graybox td { border: 1px solid #ddd; padding: 5px 25px 5px 10px; vertical-align: middle; } .graybox tr td:first-of-type { text-align: right; padding: 7px; vertical-align: top; word-break: normal; width: 40px; } .slightly-smaller { font-size: 0.9em; } .footer { padding: 8px 16px; background: #444; color: #ddd; font-size: 0.8em; } .footer p { margin: 8px 0; } .footer a { color: #fff; } html.dash .header, html.dash .breadcrumbs, html.dash .navigation { display: none; } html.dash .height-container { display: block; } form[role=search] input { font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 24px; padding: 0 10px; margin: 0; border: none; border-radius: 1em; } .loading form[role=search] input { background: white url(../img/spinner.gif) center right 4px no-repeat; } form[role=search] .tt-menu { margin: 0; min-width: 300px; background: #fbfbfb; color: #333; border: 1px solid #ddd; } form[role=search] .tt-highlight { font-weight: bold; } form[role=search] .tt-suggestion { font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; padding: 0 8px; } form[role=search] .tt-suggestion span { display: table-cell; white-space: nowrap; } form[role=search] .tt-suggestion .doc-parent-name { width: 100%; text-align: right; font-weight: normal; font-size: 0.9em; padding-left: 16px; } form[role=search] .tt-suggestion:hover, form[role=search] .tt-suggestion.tt-cursor { cursor: pointer; background-color: #4183c4; color: #fff; } form[role=search] .tt-suggestion:hover .doc-parent-name, form[role=search] .tt-suggestion.tt-cursor .doc-parent-name { color: #fff; } ================================================ FILE: docs/docsets/Hero.docset/Contents/Info.plist ================================================ CFBundleIdentifier com.jazzy.hero CFBundleName Hero DocSetPlatformFamily hero isDashDocset dashIndexFilePath index.html isJavaScriptEnabled DashDocSetFamily dashtoc ================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/BinaryOpNode.html ================================================ BinaryOpNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/CallNode.html ================================================ CallNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/ExprNode.html ================================================ ExprNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/FunctionNode.html ================================================ FunctionNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/Hero.html ================================================ Hero Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/HeroContext.html ================================================ HeroContext Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroContext

public class HeroContext

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/HeroDebugPlugin.html ================================================ HeroDebugPlugin Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/HeroExtension.html ================================================ HeroExtension Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroExtension

public class HeroExtension<Base>

Undocumented

Available where Base: UIView

  • id

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

    Declaration

    Swift

    var id: String? { get set }
  • isEnabled allows to specify whether a view and its subviews should be consider for animations. If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true

    Declaration

    Swift

    var isEnabled: Bool { get set }
  • isEnabledForSubviews allows to specify whether a view’s subviews should be consider for animations. If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true

    Declaration

    Swift

    var isEnabledForSubviews: Bool { get set }
  • Use modifiers to specify animations alongside the main transition. Checkout HeroModifier.swift for available modifiers.

    Declaration

    Swift

    var modifiers: [HeroModifier]? { get set }
  • modifierString** provides another way to set modifiers. It can be assigned through storyboard.

    Declaration

    Swift

    var modifierString: String? { get set }

Available where Base: UIViewController

Available where Base: UINavigationController

Available where Base: UITabBarController

Available where Base: UIViewController

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/HeroModifier.html ================================================ HeroModifier Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroModifier

public final class HeroModifier
extension HeroModifier: HeroStringConvertible

Undocumented

  • Undocumented

    Declaration

    Swift

    public init(applyFunction: @escaping (inout HeroTargetState) -> Void)
  • Apply modifiers directly to the view at the start of the transition. The modifiers supplied here won’t be animated. For source views, modifiers are set directly at the beginning of the animation. For destination views, they replace the target state (final appearance).

    Declaration

    Swift

    public static func beginWith(_ modifiers: [HeroModifier]) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func beginWith(modifiers: [HeroModifier]) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func beginWith(_ modifiers: HeroModifier...) -> HeroModifier
  • Use global coordinate space.

    When using global coordinate space. The view become a independent view that is not a subview of any view. It won’t move when its parent view moves, and won’t be affected by parent view’s attributes.

    When a view is matched, this is automatically enabled. The source modifier will also enable this.

    Global coordinate space is default for all views prior to version 0.1.3

    Declaration

    Swift

    public static var useGlobalCoordinateSpace: HeroModifier
  • ignore all heroModifiers attributes for a view’s direct subviews.

    Declaration

    Swift

    public static var ignoreSubviewModifiers: HeroModifier
  • ignore all heroModifiers attributes for a view’s subviews.

    • recursive: if false, will only ignore direct subviews’ modifiers. default false.

    Declaration

    Swift

    public static func ignoreSubviewModifiers(recursive: Bool = false) -> HeroModifier
  • Will create snapshot optimized for different view type. 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.

    This modifier actually does nothing by itself since .useOptimizedSnapshot is the default.

    Declaration

    Swift

    public static var useOptimizedSnapshot: HeroModifier
  • Create snapshot using snapshotView(afterScreenUpdates:).

    Declaration

    Swift

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

    Declaration

    Swift

    public static var useLayerRenderSnapshot: HeroModifier
  • Force Hero to not create any snapshot when animating this view. This will mess up the view hierarchy, therefore, view controllers have to rebuild its view structure after the transition finishes.

    Declaration

    Swift

    public static var useNoSnapshot: HeroModifier
  • Force the view to animate.

    By default, Hero will not animate if the view is outside the screen bounds or if there is no animatable hero modifier, unless this modifier is used.

    Declaration

    Swift

    public static var forceAnimate: HeroModifier
  • 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 performance.

    Declaration

    Swift

    public static var useScaleBasedSizeChange: HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func from(node: ExprNode) -> HeroModifier?
  • Fade the view during transition

    Declaration

    Swift

    public static var fade: HeroModifier
  • Force don’t fade view during transition

    Declaration

    Swift

    public static var forceNonFade: HeroModifier
  • Set the position for the view to animate from/to.

    • position: position for the view to animate from/to

    Declaration

    Swift

    public static func position(_ position: CGPoint) -> HeroModifier
  • Set the size for the view to animate from/to.

    • size: size for the view to animate from/to

    Declaration

    Swift

    public static func size(_ size: CGSize) -> HeroModifier
  • Set the transform for the view to animate from/to. Will override previous perspective, scale, translate, & rotate modifiers

    • t: the CATransform3D object

    Declaration

    Swift

    public static func transform(_ t: CATransform3D) -> HeroModifier
  • Set the perspective on the transform. use in combination with the rotate modifier.

    • perspective: set the camera distance of the transform

    Declaration

    Swift

    public static func perspective(_ perspective: CGFloat) -> HeroModifier
  • Scale 3d

    • x: scale factor on x axis, default 1
    • y: scale factor on y axis, default 1
    • z: scale factor on z axis, default 1

    Declaration

    Swift

    public static func scale(x: CGFloat = 1, y: CGFloat = 1, z: CGFloat = 1) -> HeroModifier
  • Scale in x & y axis

    • xy: scale factor in both x & y axis

    Declaration

    Swift

    public static func scale(_ xy: CGFloat) -> HeroModifier
  • Translate 3d

    • x: translation distance on x axis in display pixel, default 0
    • y: translation distance on y axis in display pixel, default 0
    • z: translation distance on z axis in display pixel, default 0

    Declaration

    Swift

    public static func translate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func translate(_ point: CGPoint, z: CGFloat = 0) -> HeroModifier
  • Rotate 3d

    • x: rotation on x axis in radian, default 0
    • y: rotation on y axis in radian, default 0
    • z: rotation on z axis in radian, default 0

    Declaration

    Swift

    public static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func rotate(_ point: CGPoint, z: CGFloat = 0) -> HeroModifier
  • Rotate 2d

    • z: rotation in radian

    Declaration

    Swift

    public static func rotate(_ z: CGFloat) -> HeroModifier

UIKit

  • Set the backgroundColor for the view to animate from/to.

    • backgroundColor: backgroundColor for the view to animate from/to

    Declaration

    Swift

    public static func backgroundColor(_ backgroundColor: UIColor) -> HeroModifier
  • Set the borderColor for the view to animate from/to.

    • borderColor: borderColor for the view to animate from/to

    Declaration

    Swift

    public static func borderColor(_ borderColor: UIColor) -> HeroModifier
  • Set the shadowColor for the view to animate from/to.

    • shadowColor: shadowColor for the view to animate from/to

    Declaration

    Swift

    public static func shadowColor(_ shadowColor: UIColor) -> HeroModifier
  • Create an overlay on the animating view.

    • color: color of the overlay
    • opacity: opacity of the overlay

    Declaration

    Swift

    public static func overlay(color: UIColor, opacity: CGFloat) -> HeroModifier
  • Set the opacity for the view to animate from/to.

    • opacity: opacity for the view to animate from/to

    Declaration

    Swift

    public static func opacity(_ opacity: CGFloat) -> HeroModifier
  • Set the cornerRadius for the view to animate from/to.

    • cornerRadius: cornerRadius for the view to animate from/to

    Declaration

    Swift

    public static func cornerRadius(_ cornerRadius: CGFloat) -> HeroModifier
  • Set the zPosition for the view to animate from/to.

    • zPosition: zPosition for the view to animate from/to

    Declaration

    Swift

    public static func zPosition(_ zPosition: CGFloat) -> HeroModifier
  • Set the contentsRect for the view to animate from/to.

    • contentsRect: contentsRect for the view to animate from/to

    Declaration

    Swift

    public static func contentsRect(_ contentsRect: CGRect) -> HeroModifier
  • Set the contentsScale for the view to animate from/to.

    • contentsScale: contentsScale for the view to animate from/to

    Declaration

    Swift

    public static func contentsScale(_ contentsScale: CGFloat) -> HeroModifier
  • Set the borderWidth for the view to animate from/to.

    • borderWidth: borderWidth for the view to animate from/to

    Declaration

    Swift

    public static func borderWidth(_ borderWidth: CGFloat) -> HeroModifier
  • Set the shadowOpacity for the view to animate from/to.

    • shadowOpacity: shadowOpacity for the view to animate from/to

    Declaration

    Swift

    public static func shadowOpacity(_ shadowOpacity: CGFloat) -> HeroModifier
  • Set the shadowOffset for the view to animate from/to.

    • shadowOffset: shadowOffset for the view to animate from/to

    Declaration

    Swift

    public static func shadowOffset(_ shadowOffset: CGSize) -> HeroModifier
  • Set the shadowRadius for the view to animate from/to.

    • shadowRadius: shadowRadius for the view to animate from/to

    Declaration

    Swift

    public static func shadowRadius(_ shadowRadius: CGFloat) -> HeroModifier
  • Set the shadowPath for the view to animate from/to.

    • shadowPath: shadowPath for the view to animate from/to

    Declaration

    Swift

    public static func shadowPath(_ shadowPath: CGPath) -> HeroModifier
  • Set the masksToBounds for the view to animate from/to.

    • masksToBounds: masksToBounds for the view to animate from/to

    Declaration

    Swift

    public static func masksToBounds(_ masksToBounds: Bool) -> HeroModifier
  • Sets the duration of the animation for a given view. If not used, Hero will use determine the duration based on the distance and size changes.

    • duration: duration of the animation

    Note: a duration of .infinity means matching the duration of the longest animation. same as .durationMatchLongest

    Declaration

    Swift

    public static func duration(_ duration: TimeInterval) -> HeroModifier
  • Sets the duration of the animation for a given view to match the longest animation of the transition.

    Declaration

    Swift

    public static var durationMatchLongest: HeroModifier
  • Sets the delay of the animation for a given view.

    • delay: delay of the animation

    Declaration

    Swift

    public static func delay(_ delay: TimeInterval) -> HeroModifier
  • Sets the timing function of the animation for a given view. If not used, Hero will use determine the timing function based on whether or not the view is entering or exiting the screen.

    • timingFunction: timing function of the animation

    Declaration

    Swift

    public static func timingFunction(_ timingFunction: CAMediaTimingFunction) -> HeroModifier
  • (iOS 9+) Use spring animation with custom stiffness & damping. The duration will be automatically calculated. Will be ignored if arc, timingFunction, or duration is set.

    • stiffness: stiffness of the spring
    • damping: damping of the spring

    Declaration

    Swift

    @available(iOS 9, *)
    public static func spring(stiffness: CGFloat, damping: CGFloat) -> HeroModifier
  • Transition from/to the state of the view with matching heroID Will also force the view to use global coordinate space.

    The following layer properties will be animated from the given view.

    position bounds.size cornerRadius transform shadowColor shadowOpacity shadowOffset shadowRadius shadowPath

    Note that the following properties won’t be taken from the source view.

    backgroundColor borderWidth borderColor

    • heroID: the source view’s heroId.

    Declaration

    Swift

    public static func source(heroID: String) -> HeroModifier
  • arc

    Works in combination with position modifier to apply a natural curve when moving to the destination.

    Declaration

    Swift

    public static var arc: HeroModifier
  • Works in combination with position modifier to apply a natural curve when moving to the destination.

    • intensity: a value of 1 represent a downward natural curve ╰. a value of -1 represent a upward curve ╮. default is 1.

    Declaration

    Swift

    public static func arc(intensity: CGFloat = 1) -> HeroModifier
  • Cascade applys increasing delay modifiers to subviews

    Declaration

    Swift

    public static var cascade: HeroModifier
  • Cascade applys increasing delay modifiers to subviews

    • delta: delay in between each animation
    • direction: cascade direction
    • delayMatchedViews: whether or not to delay matched subviews until all cascading animation have started

    Declaration

    Swift

    public static func cascade(delta: TimeInterval = 0.02,
                               direction: CascadeDirection = .topToBottom,
                               delayMatchedViews: Bool = false) -> HeroModifier
  • Apply modifiers only if the condition return true.

    Declaration

    Swift

    public static func when(_ condition: @escaping (HeroConditionalContext) -> Bool, _ modifiers: [HeroModifier]) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func when(_ condition: @escaping (HeroConditionalContext) -> Bool, _ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenMatched(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenPresenting(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenDismissing(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenAppearing(_ modifiers: HeroModifier...) -> HeroModifier
  • Undocumented

    Declaration

    Swift

    public static func whenDisappearing(_ modifiers: HeroModifier...) -> HeroModifier
================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/HeroPlugin.html ================================================ HeroPlugin Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroPlugin

open class HeroPlugin : NSObject, HeroPreprocessor, HeroAnimator

Undocumented

  • Undocumented

    Declaration

    Swift

    weak public var hero: HeroTransition!
  • Undocumented

    Declaration

    Swift

    public var context: HeroContext! { get }
  • Determines whether or not to receive seekTo callback on every frame.

    Default is false.

    When requirePerFrameCallback is false, the plugin needs to start its own animations inside animate & resume The seekTo method is only being called during an interactive transition.

    When requirePerFrameCallback is true, the plugin will receive seekTo callback on every animation frame. Hence it is possible for the plugin to do per-frame animations without implementing animate & resume

    Declaration

    Swift

    open var requirePerFrameCallback: Bool
  • Undocumented

    Declaration

    Swift

    public override required init()
  • Called before any animation. Override this method when you want to preprocess modifiers for views

    To check a view’s modifiers:

    context[view]
    context[view, "modifierName"]
    

    To set a view’s modifiers:

    context[view] = [("modifier1", ["parameter1"]), ("modifier2", [])]
    context[view, "modifier1"] = ["parameter1", "parameter2"]
    

    Declaration

    Swift

    open func process(fromViews: [UIView], toViews: [UIView])

    Parameters

    context

    object holding all parsed and changed modifiers,

    fromViews

    A flattened list of all views from source ViewController

    toViews

    A flattened list of all views from destination ViewController

  • Declaration

    Swift

    open func canAnimate(view: UIView, appearing: Bool) -> Bool

    Parameters

    context

    object holding all parsed and changed modifiers,

    view

    the view to check whether or not the plugin can handle the animation

    appearing

    true if the view is appearing(i.e. a view in destination ViewController) If return true, Hero won’t animate and won’t let any other plugins animate this view. The view will also be hidden automatically during the animation.

    Return Value

    return true if the plugin can handle animating the view.

  • Perform the animation.

    Note: views in fromViews & toViews are hidden already. Unhide then if you need to take snapshots.

    Declaration

    Swift

    open func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval

    Parameters

    context

    object holding all parsed and changed modifiers,

    fromViews

    A flattened list of all views from source ViewController (filtered by canAnimate)

    toViews

    A flattened list of all views from destination ViewController (filtered by canAnimate)

    Return Value

    The duration needed to complete the animation

  • Called when all animations are completed.

    Should perform cleanup and release any reference

    Declaration

    Swift

    open func clean()
  • For supporting interactive animation only.

    This method is called when an interactive animation is in place The plugin should pause the animation, and seek to the given progress

    Declaration

    Swift

    open func seekTo(timePassed: TimeInterval)

    Parameters

    timePassed

    time of the animation to seek to.

  • For supporting interactive animation only.

    This method is called when an interactive animation is ended The plugin should resume the animation.

    • timePassed: will be the same value since last seekTo
    • reverse: a boolean value indicating whether or not the animation should reverse

    Declaration

    Swift

    open func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval
  • For supporting interactive animation only.

    This method is called when user wants to override animation modifiers during an interactive animation

    Declaration

    Swift

    open func apply(state: HeroTargetState, to view: UIView)

    Parameters

    state

    the target state to override

    view

    the view to override

  • Undocumented

    Declaration

    Swift

    open func changeTarget(state: HeroTargetState, isDestination: Bool, to view: UIView)
  • Undocumented

    Declaration

    Swift

    public static var isEnabled: Bool { get set }
  • Undocumented

    Declaration

    Swift

    public static func enable()
  • Undocumented

    Declaration

    Swift

    public static func disable()
================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/HeroTransition.html ================================================ HeroTransition Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroTransition

open class HeroTransition : NSObject
extension HeroTransition: UINavigationControllerDelegate
extension HeroTransition: UITabBarControllerDelegate
extension HeroTransition: UIViewControllerTransitioningDelegate
extension HeroTransition: UIViewControllerAnimatedTransitioning
extension HeroTransition: UIViewControllerInteractiveTransitioning

Undocumented

Observe Progress

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/Lexer.html ================================================ Lexer Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/NumberNode.html ================================================ NumberNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/Parser.html ================================================ Parser Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/PrototypeNode.html ================================================ PrototypeNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes/VariableNode.html ================================================ VariableNode Class Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Classes.html ================================================ Classes Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Classes

The following classes are available globally.

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/CascadeDirection.html ================================================ CascadeDirection Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

CascadeDirection

public enum CascadeDirection

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroCoordinateSpace.html ================================================ HeroCoordinateSpace Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroDefaultAnimationType/Direction.html ================================================ Direction Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Direction

public enum Direction : HeroStringConvertible

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroDefaultAnimationType/Strategy.html ================================================ Strategy Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroDefaultAnimationType.html ================================================ HeroDefaultAnimationType Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroDefaultAnimationType

public enum HeroDefaultAnimationType
extension HeroDefaultAnimationType: HeroStringConvertible

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroSnapshotType.html ================================================ HeroSnapshotType Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroSnapshotType

public enum HeroSnapshotType

Undocumented

  • Will optimize for different type of views For custom views or views with masking, .optimizedDefault might create snapshots that appear differently than the actual view. In that case, use .normal or .slowRender to disable the optimization

    Declaration

    Swift

    case optimized
  • snapshotView(afterScreenUpdates:)

    Declaration

    Swift

    case normal
  • layer.render(in: currentContext)

    Declaration

    Swift

    case layerRender
  • will not create snapshot. animate the view directly. This will mess up the view hierarchy, therefore, view controllers have to rebuild its view structure after the transition finishes

    Declaration

    Swift

    case noSnapshot
================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroTransitionState.html ================================================ HeroTransitionState Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/HeroViewOrderingStrategy.html ================================================ HeroViewOrderingStrategy Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/ParseError.html ================================================ ParseError Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums/Token.html ================================================ Token Enumeration Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Enums.html ================================================ Enumerations Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Enumerations

The following enumerations are available globally.

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/CAMediaTimingFunction.html ================================================ CAMediaTimingFunction Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

CAMediaTimingFunction

public extension CAMediaTimingFunction
================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/CATransform3D.html ================================================ CATransform3D Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/HeroDebugView.html ================================================ HeroDebugView Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/String.html ================================================ String Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/UINavigationController.html ================================================ UINavigationController Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/UITabBarController.html ================================================ UITabBarController Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/UIView.html ================================================ UIView Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions/UIViewController.html ================================================ UIViewController Extension Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

UIViewController

extension UIViewController: HeroCompatible
================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Extensions.html ================================================ Extensions Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Functions.html ================================================ Functions Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroAnimator.html ================================================ HeroAnimator Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroAnimator

public protocol HeroAnimator : AnyObject

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroCompatible.html ================================================ HeroCompatible Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroCustomSnapshotView.html ================================================ HeroCustomSnapshotView Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroPreprocessor.html ================================================ HeroPreprocessor Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroProgressUpdateObserver.html ================================================ HeroProgressUpdateObserver Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroStringConvertible.html ================================================ HeroStringConvertible Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroTransitionDelegate.html ================================================ HeroTransitionDelegate Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols/HeroViewControllerDelegate.html ================================================ HeroViewControllerDelegate Protocol Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroViewControllerDelegate

@objc
public protocol HeroViewControllerDelegate

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Protocols.html ================================================ Protocols Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Protocols

The following protocols are available globally.

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Structs/HeroConditionalContext.html ================================================ HeroConditionalContext Structure Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroConditionalContext

public struct HeroConditionalContext

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Structs/HeroTargetState.html ================================================ HeroTargetState Structure Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

HeroTargetState

public struct HeroTargetState
extension HeroTargetState: ExpressibleByArrayLiteral

Undocumented

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/Structs.html ================================================ Structures Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/css/highlight.css ================================================ /*! Jazzy - https://github.com/realm/jazzy * Copyright Realm Inc. * SPDX-License-Identifier: MIT */ /* Credit to https://gist.github.com/wataru420/2048287 */ .highlight .c { color: #999988; font-style: italic; } .highlight .err { color: #a61717; background-color: #e3d2d2; } .highlight .k { color: #000000; font-weight: bold; } .highlight .o { color: #000000; font-weight: bold; } .highlight .cm { color: #999988; font-style: italic; } .highlight .cp { color: #999999; font-weight: bold; } .highlight .c1 { color: #999988; font-style: italic; } .highlight .cs { color: #999999; font-weight: bold; font-style: italic; } .highlight .gd { color: #000000; background-color: #ffdddd; } .highlight .gd .x { color: #000000; background-color: #ffaaaa; } .highlight .ge { color: #000000; font-style: italic; } .highlight .gr { color: #aa0000; } .highlight .gh { color: #999999; } .highlight .gi { color: #000000; background-color: #ddffdd; } .highlight .gi .x { color: #000000; background-color: #aaffaa; } .highlight .go { color: #888888; } .highlight .gp { color: #555555; } .highlight .gs { font-weight: bold; } .highlight .gu { color: #aaaaaa; } .highlight .gt { color: #aa0000; } .highlight .kc { color: #000000; font-weight: bold; } .highlight .kd { color: #000000; font-weight: bold; } .highlight .kp { color: #000000; font-weight: bold; } .highlight .kr { color: #000000; font-weight: bold; } .highlight .kt { color: #445588; } .highlight .m { color: #009999; } .highlight .s { color: #d14; } .highlight .na { color: #008080; } .highlight .nb { color: #0086B3; } .highlight .nc { color: #445588; font-weight: bold; } .highlight .no { color: #008080; } .highlight .ni { color: #800080; } .highlight .ne { color: #990000; font-weight: bold; } .highlight .nf { color: #990000; } .highlight .nn { color: #555555; } .highlight .nt { color: #000080; } .highlight .nv { color: #008080; } .highlight .ow { color: #000000; font-weight: bold; } .highlight .w { color: #bbbbbb; } .highlight .mf { color: #009999; } .highlight .mh { color: #009999; } .highlight .mi { color: #009999; } .highlight .mo { color: #009999; } .highlight .sb { color: #d14; } .highlight .sc { color: #d14; } .highlight .sd { color: #d14; } .highlight .s2 { color: #d14; } .highlight .se { color: #d14; } .highlight .sh { color: #d14; } .highlight .si { color: #d14; } .highlight .sx { color: #d14; } .highlight .sr { color: #009926; } .highlight .s1 { color: #d14; } .highlight .ss { color: #990073; } .highlight .bp { color: #999999; } .highlight .vc { color: #008080; } .highlight .vg { color: #008080; } .highlight .vi { color: #008080; } .highlight .il { color: #009999; } ================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/css/jazzy.css ================================================ /*! Jazzy - https://github.com/realm/jazzy * Copyright Realm Inc. * SPDX-License-Identifier: MIT */ *, *:before, *:after { box-sizing: inherit; } body { margin: 0; background: #fff; color: #333; font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; letter-spacing: .2px; -webkit-font-smoothing: antialiased; box-sizing: border-box; } h1 { font-size: 2rem; font-weight: 700; margin: 1.275em 0 0.6em; } h2 { font-size: 1.75rem; font-weight: 700; margin: 1.275em 0 0.3em; } h3 { font-size: 1.5rem; font-weight: 700; margin: 1em 0 0.3em; } h4 { font-size: 1.25rem; font-weight: 700; margin: 1.275em 0 0.85em; } h5 { font-size: 1rem; font-weight: 700; margin: 1.275em 0 0.85em; } h6 { font-size: 1rem; font-weight: 700; margin: 1.275em 0 0.85em; color: #777; } p { margin: 0 0 1em; } ul, ol { padding: 0 0 0 2em; margin: 0 0 0.85em; } blockquote { margin: 0 0 0.85em; padding: 0 15px; color: #858585; border-left: 4px solid #e5e5e5; } img { max-width: 100%; } a { color: #4183c4; text-decoration: none; } a:hover, a:focus { outline: 0; text-decoration: underline; } a.discouraged { text-decoration: line-through; } a.discouraged:hover, a.discouraged:focus { text-decoration: underline line-through; } table { background: #fff; width: 100%; border-collapse: collapse; border-spacing: 0; overflow: auto; margin: 0 0 0.85em; } tr:nth-child(2n) { background-color: #fbfbfb; } th, td { padding: 6px 13px; border: 1px solid #ddd; } hr { height: 1px; border: none; background-color: #ddd; } pre { margin: 0 0 1.275em; padding: .85em 1em; overflow: auto; background: #f7f7f7; font-size: .85em; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } code { font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; } .item-container p > code, .item-container li > code, .top-matter p > code, .top-matter li > code { background: #f7f7f7; padding: .2em; } .item-container p > code:before, .item-container p > code:after, .item-container li > code:before, .item-container li > code:after, .top-matter p > code:before, .top-matter p > code:after, .top-matter li > code:before, .top-matter li > code:after { letter-spacing: -.2em; content: "\00a0"; } pre code { padding: 0; white-space: pre; } .content-wrapper { display: flex; flex-direction: column; } @media (min-width: 768px) { .content-wrapper { flex-direction: row; } } .header { display: flex; padding: 8px; font-size: 0.875em; background: #444; color: #999; } .header-col { margin: 0; padding: 0 8px; } .header-col--primary { flex: 1; } .header-link { color: #fff; } .header-icon { padding-right: 2px; vertical-align: -3px; height: 16px; } .breadcrumbs { font-size: 0.875em; padding: 8px 16px; margin: 0; background: #fbfbfb; border-bottom: 1px solid #ddd; } .carat { height: 10px; margin: 0 5px; } .navigation { order: 2; } @media (min-width: 768px) { .navigation { order: 1; width: 25%; max-width: 300px; padding-bottom: 64px; overflow: hidden; word-wrap: normal; background: #fbfbfb; border-right: 1px solid #ddd; } } .nav-groups { list-style-type: none; padding-left: 0; } .nav-group-name { border-bottom: 1px solid #ddd; padding: 8px 0 8px 16px; } .nav-group-name-link { color: #333; } .nav-group-tasks { margin: 8px 0; padding: 0 0 0 8px; } .nav-group-task { font-size: 1em; list-style-type: none; white-space: nowrap; } .nav-group-task-link { color: #808080; } .main-content { order: 1; } @media (min-width: 768px) { .main-content { order: 2; flex: 1; padding-bottom: 60px; } } .section { padding: 0 32px; border-bottom: 1px solid #ddd; } .section-content { max-width: 834px; margin: 0 auto; padding: 16px 0; } .section-name { color: #666; display: block; } .section-name p { margin-bottom: inherit; } .declaration .highlight { overflow-x: initial; padding: 8px 0; margin: 0; background-color: transparent; border: none; } .task-group-section { border-top: 1px solid #ddd; } .task-group { padding-top: 0px; } .task-name-container a[name]:before { content: ""; display: block; } .section-name-container { position: relative; } .section-name-container .section-name-link { position: absolute; top: 0; left: 0; bottom: 0; right: 0; margin-bottom: 0; } .section-name-container .section-name { position: relative; pointer-events: none; z-index: 1; } .section-name-container .section-name a { pointer-events: auto; } .item-container { padding: 0; } .item { padding-top: 8px; width: 100%; list-style-type: none; } .item a[name]:before { content: ""; display: block; } .item .token, .item .direct-link { display: inline-block; text-indent: -20px; padding-left: 3px; margin-left: 20px; font-size: 1rem; } .item .declaration-note { font-size: .85em; color: #808080; font-style: italic; } .pointer-container { border-bottom: 1px solid #ddd; left: -23px; padding-bottom: 13px; position: relative; width: 110%; } .pointer { left: 21px; top: 7px; display: block; position: absolute; width: 12px; height: 12px; border-left: 1px solid #ddd; border-top: 1px solid #ddd; background: #fff; transform: rotate(45deg); } .height-container { display: none; position: relative; width: 100%; overflow: hidden; } .height-container .section { background: #fff; border: 1px solid #ddd; border-top-width: 0; padding-top: 10px; padding-bottom: 5px; padding: 8px 16px; } .aside, .language { padding: 6px 12px; margin: 12px 0; border-left: 5px solid #dddddd; overflow-y: hidden; } .aside .aside-title, .language .aside-title { font-size: 9px; letter-spacing: 2px; text-transform: uppercase; padding-bottom: 0; margin: 0; color: #aaa; -webkit-user-select: none; } .aside p:last-child, .language p:last-child { margin-bottom: 0; } .language { border-left: 5px solid #cde9f4; } .language .aside-title { color: #4183c4; } .aside-warning, .aside-deprecated, .aside-unavailable { border-left: 5px solid #ff6666; } .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { color: #ff0000; } .graybox { border-collapse: collapse; width: 100%; } .graybox p { margin: 0; word-break: break-word; min-width: 50px; } .graybox td { border: 1px solid #ddd; padding: 5px 25px 5px 10px; vertical-align: middle; } .graybox tr td:first-of-type { text-align: right; padding: 7px; vertical-align: top; word-break: normal; width: 40px; } .slightly-smaller { font-size: 0.9em; } .footer { padding: 8px 16px; background: #444; color: #ddd; font-size: 0.8em; } .footer p { margin: 8px 0; } .footer a { color: #fff; } html.dash .header, html.dash .breadcrumbs, html.dash .navigation { display: none; } html.dash .height-container { display: block; } form[role=search] input { font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 24px; padding: 0 10px; margin: 0; border: none; border-radius: 1em; } .loading form[role=search] input { background: white url(../img/spinner.gif) center right 4px no-repeat; } form[role=search] .tt-menu { margin: 0; min-width: 300px; background: #fbfbfb; color: #333; border: 1px solid #ddd; } form[role=search] .tt-highlight { font-weight: bold; } form[role=search] .tt-suggestion { font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif; padding: 0 8px; } form[role=search] .tt-suggestion span { display: table-cell; white-space: nowrap; } form[role=search] .tt-suggestion .doc-parent-name { width: 100%; text-align: right; font-weight: normal; font-size: 0.9em; padding-left: 16px; } form[role=search] .tt-suggestion:hover, form[role=search] .tt-suggestion.tt-cursor { cursor: pointer; background-color: #4183c4; color: #fff; } form[role=search] .tt-suggestion:hover .doc-parent-name, form[role=search] .tt-suggestion.tt-cursor .doc-parent-name { color: #fff; } ================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/index.html ================================================ Hero Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Hero is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit’s cumbersome transition APIs—making custom transitions an easy task for developers.

Carthage compatible Accio supported codecov Version License Xcode 10.0+ iOS 10.0+ Swift 4.0+ 中文 README Donate

Unit Test Swift PM

      

Hero is similar to Keynote’s Magic Move. It checks the heroID property on all source and destination views. Every matched view pair is then automatically transitioned from its old state to its new state.

Hero can also construct animations for unmatched views. It is easy to define these animations via the heroModifiers property. Hero will run these animations alongside the Magic Move animations. All of these animations can be interactively controlled by user gestures.

At view controller level, Hero provides several template transitions that you can set through heroModalAnimationType, heroNavigationAnimationType, and heroTabBarAnimationType. These can be used as the foundation of your custom transitions. Combine with heroID & heroModifiers to make your own unique transitions.

      

By default, Hero provides dynamic duration based on the Material Design Motion Guide. Duration is automatically determined by changes to distance and size—saving you the hassle, while providing consistent and delightful animations.

Hero doesn’t make any assumptions about how the view is built or structured. It won’t modify any of your views’ states other than hiding them during the animation. This makes it work with Auto Layout, programmatic layout, UICollectionView (without modifying its layout object), UITableView, UINavigationController, UITabBarController, etc…

Usage Example 1

View Controller 1

redView.hero.id = "ironMan"
blackView.hero.id = "batMan"

View Controller 2

self.hero.isEnabled = true
redView.hero.id = "ironMan"
blackView.hero.id = "batMan"
whiteView.hero.modifiers = [.translate(y:100)]

Usage Example 2

View Controller 1

greyView.hero.id = "skyWalker"

View Controller 2

self.hero.isEnabled = true
greyView.hero.id = "skyWalker"

// collectionView is the parent view of all red cells
collectionView.hero.modifiers = [.cascade]
for cell in redCells {
    cell.hero.modifiers = [.fade, .scale(0.5)]
}

You can do these in the storyboard too!

Installation

CocoaPods

Add the following entry to your Podfile:

pod 'Hero'

Then run pod install.

Don’t forget to import Hero in every file you’d like to use Hero.

Carthage

Add the following entry to your Cartfile:

github "HeroTransitions/Hero"

Then run carthage update.

If this is your first time using Carthage in the project, you’ll need to go through some additional steps as explained over at Carthage.

Accio

Add the following to your Package.swift:

.package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.4.0")),

Next, add Hero to your App targets dependencies like so:

.target(
    name: "App",
    dependencies: [
        "Hero",
    ]
),

Then run accio update.

Swift Package Manager

To integrate using Apple’s Swift package manager, add the following as a dependency to your Package.swift:

.package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.3.0"))

and then specify "Hero" as a dependency of the Target in which you wish to use Hero. Here’s an example PackageDescription:

// swift-tools-version:4.0
import PackageDescription

let package = Package(
    name: "MyPackage",
    products: [
        .library(
            name: "MyPackage",
            targets: ["MyPackage"]),
    ],
    dependencies: [
        .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.6.3"))
    ],
    targets: [
        .target(
            name: "MyPackage",
            dependencies: ["Hero"])
    ]
)

Manually

  • Drag the Sources folder anywhere in your project.

Documentations

Checkout the WIKI PAGES (Usage Guide) for documentations.

For more up-to-date ones, please see the header-doc. (use alt+click in Xcode)

Dash compatible API docs: https://HeroTransitions.github.io/Hero/

Interactive Transition Tutorials

Interactive transitions with Hero (Part 1)

FAQ

Not able to use Hero transition even when self.hero.isEnabled is set to true

Make sure that you have also enabled self.hero.isEnabled on the navigation controller if you are doing a push/pop inside the navigation controller.

Views being covered by another matched view during the transition

Matched views use global coordinate space while unmatched views use local coordinate space by default. Local coordinate spaced views might be covered by other global coordinate spaced views. To solve this, use the useGlobalCoordinateSpace modifier on the views being covered. Checkout Coordinate Space Wiki page for details.

Push animation is shown along side my custom animation

This is the default animation for navigation controller provided by Hero. To disable the push animation, set self.hero.navigationAnimationType to .fade or .none on the navigation controller.

How do I use a different default animation when dismissing

You can use the animation type .selectBy(presenting:dismissing) to specify a different default animation for dismiss.

For example:

    self.hero.modalAnimationType = .selectBy(presenting:.zoom, dismissing:.zoomOut)

Contribute

We welcome any contributions. Please read the Contribution Guide.

================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/js/jazzy.js ================================================ // Jazzy - https://github.com/realm/jazzy // Copyright Realm Inc. // SPDX-License-Identifier: MIT window.jazzy = {'docset': false} if (typeof window.dash != 'undefined') { document.documentElement.className += ' dash' window.jazzy.docset = true } if (navigator.userAgent.match(/xcode/i)) { document.documentElement.className += ' xcode' window.jazzy.docset = true } function toggleItem($link, $content) { var animationDuration = 300; $link.toggleClass('token-open'); $content.slideToggle(animationDuration); } function itemLinkToContent($link) { return $link.parent().parent().next(); } // On doc load + hash-change, open any targetted item function openCurrentItemIfClosed() { if (window.jazzy.docset) { return; } var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token'); $content = itemLinkToContent($link); if ($content.is(':hidden')) { toggleItem($link, $content); } } $(openCurrentItemIfClosed); $(window).on('hashchange', openCurrentItemIfClosed); // On item link ('token') click, toggle its discussion $('.token').on('click', function(event) { if (window.jazzy.docset) { return; } var $link = $(this); toggleItem($link, itemLinkToContent($link)); // Keeps the document from jumping to the hash. var href = $link.attr('href'); if (history.pushState) { history.pushState({}, '', href); } else { location.hash = href; } event.preventDefault(); }); // Clicks on links to the current, closed, item need to open the item $("a:not('.token')").on('click', function() { if (location == this.href) { openCurrentItemIfClosed(); } }); // KaTeX rendering if ("katex" in window) { $($('.math').each( (_, element) => { katex.render(element.textContent, element, { displayMode: $(element).hasClass('m-block'), throwOnError: false, trust: true }); })) } ================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/js/jazzy.search.js ================================================ // Jazzy - https://github.com/realm/jazzy // Copyright Realm Inc. // SPDX-License-Identifier: MIT $(function(){ var $typeahead = $('[data-typeahead]'); var $form = $typeahead.parents('form'); var searchURL = $form.attr('action'); function displayTemplate(result) { return result.name; } function suggestionTemplate(result) { var t = '
'; t += '' + result.name + ''; if (result.parent_name) { t += '' + result.parent_name + ''; } t += '
'; return t; } $typeahead.one('focus', function() { $form.addClass('loading'); $.getJSON(searchURL).then(function(searchData) { const searchIndex = lunr(function() { this.ref('url'); this.field('name'); this.field('abstract'); for (const [url, doc] of Object.entries(searchData)) { this.add({url: url, name: doc.name, abstract: doc.abstract}); } }); $typeahead.typeahead( { highlight: true, minLength: 3, autoselect: true }, { limit: 10, display: displayTemplate, templates: { suggestion: suggestionTemplate }, source: function(query, sync) { const lcSearch = query.toLowerCase(); const results = searchIndex.query(function(q) { q.term(lcSearch, { boost: 100 }); q.term(lcSearch, { boost: 10, wildcard: lunr.Query.wildcard.TRAILING }); }).map(function(result) { var doc = searchData[result.ref]; doc.url = result.ref; return doc; }); sync(results); } } ); $form.removeClass('loading'); $typeahead.trigger('focus'); }); }); var baseURL = searchURL.slice(0, -"search.json".length); $typeahead.on('typeahead:select', function(e, result) { window.location = baseURL + result.url; }); }); ================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/js/typeahead.jquery.js ================================================ /*! * typeahead.js 1.3.1 * https://github.com/corejavascript/typeahead.js * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT */ (function(root, factory) { if (typeof define === "function" && define.amd) { define([ "jquery" ], function(a0) { return factory(a0); }); } else if (typeof module === "object" && module.exports) { module.exports = factory(require("jquery")); } else { factory(root["jQuery"]); } })(this, function($) { var _ = function() { "use strict"; return { isMsie: function() { return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; }, isBlankString: function(str) { return !str || /^\s*$/.test(str); }, escapeRegExChars: function(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }, isString: function(obj) { return typeof obj === "string"; }, isNumber: function(obj) { return typeof obj === "number"; }, isArray: $.isArray, isFunction: $.isFunction, isObject: $.isPlainObject, isUndefined: function(obj) { return typeof obj === "undefined"; }, isElement: function(obj) { return !!(obj && obj.nodeType === 1); }, isJQuery: function(obj) { return obj instanceof $; }, toStr: function toStr(s) { return _.isUndefined(s) || s === null ? "" : s + ""; }, bind: $.proxy, each: function(collection, cb) { $.each(collection, reverseArgs); function reverseArgs(index, value) { return cb(value, index); } }, map: $.map, filter: $.grep, every: function(obj, test) { var result = true; if (!obj) { return result; } $.each(obj, function(key, val) { if (!(result = test.call(null, val, key, obj))) { return false; } }); return !!result; }, some: function(obj, test) { var result = false; if (!obj) { return result; } $.each(obj, function(key, val) { if (result = test.call(null, val, key, obj)) { return false; } }); return !!result; }, mixin: $.extend, identity: function(x) { return x; }, clone: function(obj) { return $.extend(true, {}, obj); }, getIdGenerator: function() { var counter = 0; return function() { return counter++; }; }, templatify: function templatify(obj) { return $.isFunction(obj) ? obj : template; function template() { return String(obj); } }, defer: function(fn) { setTimeout(fn, 0); }, debounce: function(func, wait, immediate) { var timeout, result; return function() { var context = this, args = arguments, later, callNow; later = function() { timeout = null; if (!immediate) { result = func.apply(context, args); } }; callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); } return result; }; }, throttle: function(func, wait) { var context, args, timeout, result, previous, later; previous = 0; later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(), remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }, stringify: function(val) { return _.isString(val) ? val : JSON.stringify(val); }, guid: function() { function _p8(s) { var p = (Math.random().toString(16) + "000000000").substr(2, 8); return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p; } return "tt-" + _p8() + _p8(true) + _p8(true) + _p8(); }, noop: function() {} }; }(); var WWW = function() { "use strict"; var defaultClassNames = { wrapper: "twitter-typeahead", input: "tt-input", hint: "tt-hint", menu: "tt-menu", dataset: "tt-dataset", suggestion: "tt-suggestion", selectable: "tt-selectable", empty: "tt-empty", open: "tt-open", cursor: "tt-cursor", highlight: "tt-highlight" }; return build; function build(o) { var www, classes; classes = _.mixin({}, defaultClassNames, o); www = { css: buildCss(), classes: classes, html: buildHtml(classes), selectors: buildSelectors(classes) }; return { css: www.css, html: www.html, classes: www.classes, selectors: www.selectors, mixin: function(o) { _.mixin(o, www); } }; } function buildHtml(c) { return { wrapper: '', menu: '
' }; } function buildSelectors(classes) { var selectors = {}; _.each(classes, function(v, k) { selectors[k] = "." + v; }); return selectors; } function buildCss() { var css = { wrapper: { position: "relative", display: "inline-block" }, hint: { position: "absolute", top: "0", left: "0", borderColor: "transparent", boxShadow: "none", opacity: "1" }, input: { position: "relative", verticalAlign: "top", backgroundColor: "transparent" }, inputWithNoHint: { position: "relative", verticalAlign: "top" }, menu: { position: "absolute", top: "100%", left: "0", zIndex: "100", display: "none" }, ltr: { left: "0", right: "auto" }, rtl: { left: "auto", right: " 0" } }; if (_.isMsie()) { _.mixin(css.input, { backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" }); } return css; } }(); var EventBus = function() { "use strict"; var namespace, deprecationMap; namespace = "typeahead:"; deprecationMap = { render: "rendered", cursorchange: "cursorchanged", select: "selected", autocomplete: "autocompleted" }; function EventBus(o) { if (!o || !o.el) { $.error("EventBus initialized without el"); } this.$el = $(o.el); } _.mixin(EventBus.prototype, { _trigger: function(type, args) { var $e = $.Event(namespace + type); this.$el.trigger.call(this.$el, $e, args || []); return $e; }, before: function(type) { var args, $e; args = [].slice.call(arguments, 1); $e = this._trigger("before" + type, args); return $e.isDefaultPrevented(); }, trigger: function(type) { var deprecatedType; this._trigger(type, [].slice.call(arguments, 1)); if (deprecatedType = deprecationMap[type]) { this._trigger(deprecatedType, [].slice.call(arguments, 1)); } } }); return EventBus; }(); var EventEmitter = function() { "use strict"; var splitter = /\s+/, nextTick = getNextTick(); return { onSync: onSync, onAsync: onAsync, off: off, trigger: trigger }; function on(method, types, cb, context) { var type; if (!cb) { return this; } types = types.split(splitter); cb = context ? bindContext(cb, context) : cb; this._callbacks = this._callbacks || {}; while (type = types.shift()) { this._callbacks[type] = this._callbacks[type] || { sync: [], async: [] }; this._callbacks[type][method].push(cb); } return this; } function onAsync(types, cb, context) { return on.call(this, "async", types, cb, context); } function onSync(types, cb, context) { return on.call(this, "sync", types, cb, context); } function off(types) { var type; if (!this._callbacks) { return this; } types = types.split(splitter); while (type = types.shift()) { delete this._callbacks[type]; } return this; } function trigger(types) { var type, callbacks, args, syncFlush, asyncFlush; if (!this._callbacks) { return this; } types = types.split(splitter); args = [].slice.call(arguments, 1); while ((type = types.shift()) && (callbacks = this._callbacks[type])) { syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); syncFlush() && nextTick(asyncFlush); } return this; } function getFlush(callbacks, context, args) { return flush; function flush() { var cancelled; for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { cancelled = callbacks[i].apply(context, args) === false; } return !cancelled; } } function getNextTick() { var nextTickFn; if (window.setImmediate) { nextTickFn = function nextTickSetImmediate(fn) { setImmediate(function() { fn(); }); }; } else { nextTickFn = function nextTickSetTimeout(fn) { setTimeout(function() { fn(); }, 0); }; } return nextTickFn; } function bindContext(fn, context) { return fn.bind ? fn.bind(context) : function() { fn.apply(context, [].slice.call(arguments, 0)); }; } }(); var highlight = function(doc) { "use strict"; var defaults = { node: null, pattern: null, tagName: "strong", className: null, wordsOnly: false, caseSensitive: false, diacriticInsensitive: false }; var accented = { A: "[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]", B: "[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]", C: "[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]", D: "[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]", E: "[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]", F: "[FfᶠḞḟ℉ℱ℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]", G: "[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]", H: "[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]", I: "[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]", J: "[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]", K: "[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]", L: "[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]", M: "[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]", N: "[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]", O: "[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]", P: "[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]", Q: "[Qqℚ⒬Ⓠⓠ㏃Qq]", R: "[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]", S: "[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]", T: "[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]", U: "[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]", V: "[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]", W: "[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]", X: "[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]", Y: "[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]", Z: "[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]" }; return function hightlight(o) { var regex; o = _.mixin({}, defaults, o); if (!o.node || !o.pattern) { return; } o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly, o.diacriticInsensitive); traverse(o.node, hightlightTextNode); function hightlightTextNode(textNode) { var match, patternNode, wrapperNode; if (match = regex.exec(textNode.data)) { wrapperNode = doc.createElement(o.tagName); o.className && (wrapperNode.className = o.className); patternNode = textNode.splitText(match.index); patternNode.splitText(match[0].length); wrapperNode.appendChild(patternNode.cloneNode(true)); textNode.parentNode.replaceChild(wrapperNode, patternNode); } return !!match; } function traverse(el, hightlightTextNode) { var childNode, TEXT_NODE_TYPE = 3; for (var i = 0; i < el.childNodes.length; i++) { childNode = el.childNodes[i]; if (childNode.nodeType === TEXT_NODE_TYPE) { i += hightlightTextNode(childNode) ? 1 : 0; } else { traverse(childNode, hightlightTextNode); } } } }; function accent_replacer(chr) { return accented[chr.toUpperCase()] || chr; } function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensitive) { var escapedPatterns = [], regexStr; for (var i = 0, len = patterns.length; i < len; i++) { var escapedWord = _.escapeRegExChars(patterns[i]); if (diacriticInsensitive) { escapedWord = escapedWord.replace(/\S/g, accent_replacer); } escapedPatterns.push(escapedWord); } regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); } }(window.document); var Input = function() { "use strict"; var specialKeyCodeMap; specialKeyCodeMap = { 9: "tab", 27: "esc", 37: "left", 39: "right", 13: "enter", 38: "up", 40: "down" }; function Input(o, www) { var id; o = o || {}; if (!o.input) { $.error("input is missing"); } www.mixin(this); this.$hint = $(o.hint); this.$input = $(o.input); this.$menu = $(o.menu); id = this.$input.attr("id") || _.guid(); this.$menu.attr("id", id + "_listbox"); this.$hint.attr({ "aria-hidden": true }); this.$input.attr({ "aria-owns": id + "_listbox", role: "combobox", "aria-autocomplete": "list", "aria-expanded": false }); this.query = this.$input.val(); this.queryWhenFocused = this.hasFocus() ? this.query : null; this.$overflowHelper = buildOverflowHelper(this.$input); this._checkLanguageDirection(); if (this.$hint.length === 0) { this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; } this.onSync("cursorchange", this._updateDescendent); } Input.normalizeQuery = function(str) { return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); }; _.mixin(Input.prototype, EventEmitter, { _onBlur: function onBlur() { this.resetInputValue(); this.trigger("blurred"); }, _onFocus: function onFocus() { this.queryWhenFocused = this.query; this.trigger("focused"); }, _onKeydown: function onKeydown($e) { var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; this._managePreventDefault(keyName, $e); if (keyName && this._shouldTrigger(keyName, $e)) { this.trigger(keyName + "Keyed", $e); } }, _onInput: function onInput() { this._setQuery(this.getInputValue()); this.clearHintIfInvalid(); this._checkLanguageDirection(); }, _managePreventDefault: function managePreventDefault(keyName, $e) { var preventDefault; switch (keyName) { case "up": case "down": preventDefault = !withModifier($e); break; default: preventDefault = false; } preventDefault && $e.preventDefault(); }, _shouldTrigger: function shouldTrigger(keyName, $e) { var trigger; switch (keyName) { case "tab": trigger = !withModifier($e); break; default: trigger = true; } return trigger; }, _checkLanguageDirection: function checkLanguageDirection() { var dir = (this.$input.css("direction") || "ltr").toLowerCase(); if (this.dir !== dir) { this.dir = dir; this.$hint.attr("dir", dir); this.trigger("langDirChanged", dir); } }, _setQuery: function setQuery(val, silent) { var areEquivalent, hasDifferentWhitespace; areEquivalent = areQueriesEquivalent(val, this.query); hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; this.query = val; if (!silent && !areEquivalent) { this.trigger("queryChanged", this.query); } else if (!silent && hasDifferentWhitespace) { this.trigger("whitespaceChanged", this.query); } }, _updateDescendent: function updateDescendent(event, id) { this.$input.attr("aria-activedescendant", id); }, bind: function() { var that = this, onBlur, onFocus, onKeydown, onInput; onBlur = _.bind(this._onBlur, this); onFocus = _.bind(this._onFocus, this); onKeydown = _.bind(this._onKeydown, this); onInput = _.bind(this._onInput, this); this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); if (!_.isMsie() || _.isMsie() > 9) { this.$input.on("input.tt", onInput); } else { this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { if (specialKeyCodeMap[$e.which || $e.keyCode]) { return; } _.defer(_.bind(that._onInput, that, $e)); }); } return this; }, focus: function focus() { this.$input.focus(); }, blur: function blur() { this.$input.blur(); }, getLangDir: function getLangDir() { return this.dir; }, getQuery: function getQuery() { return this.query || ""; }, setQuery: function setQuery(val, silent) { this.setInputValue(val); this._setQuery(val, silent); }, hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { return this.query !== this.queryWhenFocused; }, getInputValue: function getInputValue() { return this.$input.val(); }, setInputValue: function setInputValue(value) { this.$input.val(value); this.clearHintIfInvalid(); this._checkLanguageDirection(); }, resetInputValue: function resetInputValue() { this.setInputValue(this.query); }, getHint: function getHint() { return this.$hint.val(); }, setHint: function setHint(value) { this.$hint.val(value); }, clearHint: function clearHint() { this.setHint(""); }, clearHintIfInvalid: function clearHintIfInvalid() { var val, hint, valIsPrefixOfHint, isValid; val = this.getInputValue(); hint = this.getHint(); valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); !isValid && this.clearHint(); }, hasFocus: function hasFocus() { return this.$input.is(":focus"); }, hasOverflow: function hasOverflow() { var constraint = this.$input.width() - 2; this.$overflowHelper.text(this.getInputValue()); return this.$overflowHelper.width() >= constraint; }, isCursorAtEnd: function() { var valueLength, selectionStart, range; valueLength = this.$input.val().length; selectionStart = this.$input[0].selectionStart; if (_.isNumber(selectionStart)) { return selectionStart === valueLength; } else if (document.selection) { range = document.selection.createRange(); range.moveStart("character", -valueLength); return valueLength === range.text.length; } return true; }, destroy: function destroy() { this.$hint.off(".tt"); this.$input.off(".tt"); this.$overflowHelper.remove(); this.$hint = this.$input = this.$overflowHelper = $("
"); }, setAriaExpanded: function setAriaExpanded(value) { this.$input.attr("aria-expanded", value); } }); return Input; function buildOverflowHelper($input) { return $('').css({ position: "absolute", visibility: "hidden", whiteSpace: "pre", fontFamily: $input.css("font-family"), fontSize: $input.css("font-size"), fontStyle: $input.css("font-style"), fontVariant: $input.css("font-variant"), fontWeight: $input.css("font-weight"), wordSpacing: $input.css("word-spacing"), letterSpacing: $input.css("letter-spacing"), textIndent: $input.css("text-indent"), textRendering: $input.css("text-rendering"), textTransform: $input.css("text-transform") }).insertAfter($input); } function areQueriesEquivalent(a, b) { return Input.normalizeQuery(a) === Input.normalizeQuery(b); } function withModifier($e) { return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; } }(); var Dataset = function() { "use strict"; var keys, nameGenerator; keys = { dataset: "tt-selectable-dataset", val: "tt-selectable-display", obj: "tt-selectable-object" }; nameGenerator = _.getIdGenerator(); function Dataset(o, www) { o = o || {}; o.templates = o.templates || {}; o.templates.notFound = o.templates.notFound || o.templates.empty; if (!o.source) { $.error("missing source"); } if (!o.node) { $.error("missing node"); } if (o.name && !isValidName(o.name)) { $.error("invalid dataset name: " + o.name); } www.mixin(this); this.highlight = !!o.highlight; this.name = _.toStr(o.name || nameGenerator()); this.limit = o.limit || 5; this.displayFn = getDisplayFn(o.display || o.displayKey); this.templates = getTemplates(o.templates, this.displayFn); this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; this._resetLastSuggestion(); this.$el = $(o.node).attr("role", "presentation").addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); } Dataset.extractData = function extractData(el) { var $el = $(el); if ($el.data(keys.obj)) { return { dataset: $el.data(keys.dataset) || "", val: $el.data(keys.val) || "", obj: $el.data(keys.obj) || null }; } return null; }; _.mixin(Dataset.prototype, EventEmitter, { _overwrite: function overwrite(query, suggestions) { suggestions = suggestions || []; if (suggestions.length) { this._renderSuggestions(query, suggestions); } else if (this.async && this.templates.pending) { this._renderPending(query); } else if (!this.async && this.templates.notFound) { this._renderNotFound(query); } else { this._empty(); } this.trigger("rendered", suggestions, false, this.name); }, _append: function append(query, suggestions) { suggestions = suggestions || []; if (suggestions.length && this.$lastSuggestion.length) { this._appendSuggestions(query, suggestions); } else if (suggestions.length) { this._renderSuggestions(query, suggestions); } else if (!this.$lastSuggestion.length && this.templates.notFound) { this._renderNotFound(query); } this.trigger("rendered", suggestions, true, this.name); }, _renderSuggestions: function renderSuggestions(query, suggestions) { var $fragment; $fragment = this._getSuggestionsFragment(query, suggestions); this.$lastSuggestion = $fragment.children().last(); this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions)); }, _appendSuggestions: function appendSuggestions(query, suggestions) { var $fragment, $lastSuggestion; $fragment = this._getSuggestionsFragment(query, suggestions); $lastSuggestion = $fragment.children().last(); this.$lastSuggestion.after($fragment); this.$lastSuggestion = $lastSuggestion; }, _renderPending: function renderPending(query) { var template = this.templates.pending; this._resetLastSuggestion(); template && this.$el.html(template({ query: query, dataset: this.name })); }, _renderNotFound: function renderNotFound(query) { var template = this.templates.notFound; this._resetLastSuggestion(); template && this.$el.html(template({ query: query, dataset: this.name })); }, _empty: function empty() { this.$el.empty(); this._resetLastSuggestion(); }, _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) { var that = this, fragment; fragment = document.createDocumentFragment(); _.each(suggestions, function getSuggestionNode(suggestion) { var $el, context; context = that._injectQuery(query, suggestion); $el = $(that.templates.suggestion(context)).data(keys.dataset, that.name).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); fragment.appendChild($el[0]); }); this.highlight && highlight({ className: this.classes.highlight, node: fragment, pattern: query }); return $(fragment); }, _getFooter: function getFooter(query, suggestions) { return this.templates.footer ? this.templates.footer({ query: query, suggestions: suggestions, dataset: this.name }) : null; }, _getHeader: function getHeader(query, suggestions) { return this.templates.header ? this.templates.header({ query: query, suggestions: suggestions, dataset: this.name }) : null; }, _resetLastSuggestion: function resetLastSuggestion() { this.$lastSuggestion = $(); }, _injectQuery: function injectQuery(query, obj) { return _.isObject(obj) ? _.mixin({ _query: query }, obj) : obj; }, update: function update(query) { var that = this, canceled = false, syncCalled = false, rendered = 0; this.cancel(); this.cancel = function cancel() { canceled = true; that.cancel = $.noop; that.async && that.trigger("asyncCanceled", query, that.name); }; this.source(query, sync, async); !syncCalled && sync([]); function sync(suggestions) { if (syncCalled) { return; } syncCalled = true; suggestions = (suggestions || []).slice(0, that.limit); rendered = suggestions.length; that._overwrite(query, suggestions); if (rendered < that.limit && that.async) { that.trigger("asyncRequested", query, that.name); } } function async(suggestions) { suggestions = suggestions || []; if (!canceled && rendered < that.limit) { that.cancel = $.noop; var idx = Math.abs(rendered - that.limit); rendered += idx; that._append(query, suggestions.slice(0, idx)); that.async && that.trigger("asyncReceived", query, that.name); } } }, cancel: $.noop, clear: function clear() { this._empty(); this.cancel(); this.trigger("cleared"); }, isEmpty: function isEmpty() { return this.$el.is(":empty"); }, destroy: function destroy() { this.$el = $("
"); } }); return Dataset; function getDisplayFn(display) { display = display || _.stringify; return _.isFunction(display) ? display : displayFn; function displayFn(obj) { return obj[display]; } } function getTemplates(templates, displayFn) { return { notFound: templates.notFound && _.templatify(templates.notFound), pending: templates.pending && _.templatify(templates.pending), header: templates.header && _.templatify(templates.header), footer: templates.footer && _.templatify(templates.footer), suggestion: templates.suggestion ? userSuggestionTemplate : suggestionTemplate }; function userSuggestionTemplate(context) { var template = templates.suggestion; return $(template(context)).attr("id", _.guid()); } function suggestionTemplate(context) { return $('
').attr("id", _.guid()).text(displayFn(context)); } } function isValidName(str) { return /^[_a-zA-Z0-9-]+$/.test(str); } }(); var Menu = function() { "use strict"; function Menu(o, www) { var that = this; o = o || {}; if (!o.node) { $.error("node is required"); } www.mixin(this); this.$node = $(o.node); this.query = null; this.datasets = _.map(o.datasets, initializeDataset); function initializeDataset(oDataset) { var node = that.$node.find(oDataset.node).first(); oDataset.node = node.length ? node : $("
").appendTo(that.$node); return new Dataset(oDataset, www); } } _.mixin(Menu.prototype, EventEmitter, { _onSelectableClick: function onSelectableClick($e) { this.trigger("selectableClicked", $($e.currentTarget)); }, _onRendered: function onRendered(type, dataset, suggestions, async) { this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); this.trigger("datasetRendered", dataset, suggestions, async); }, _onCleared: function onCleared() { this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); this.trigger("datasetCleared"); }, _propagate: function propagate() { this.trigger.apply(this, arguments); }, _allDatasetsEmpty: function allDatasetsEmpty() { return _.every(this.datasets, _.bind(function isDatasetEmpty(dataset) { var isEmpty = dataset.isEmpty(); this.$node.attr("aria-expanded", !isEmpty); return isEmpty; }, this)); }, _getSelectables: function getSelectables() { return this.$node.find(this.selectors.selectable); }, _removeCursor: function _removeCursor() { var $selectable = this.getActiveSelectable(); $selectable && $selectable.removeClass(this.classes.cursor); }, _ensureVisible: function ensureVisible($el) { var elTop, elBottom, nodeScrollTop, nodeHeight; elTop = $el.position().top; elBottom = elTop + $el.outerHeight(true); nodeScrollTop = this.$node.scrollTop(); nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10); if (elTop < 0) { this.$node.scrollTop(nodeScrollTop + elTop); } else if (nodeHeight < elBottom) { this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight)); } }, bind: function() { var that = this, onSelectableClick; onSelectableClick = _.bind(this._onSelectableClick, this); this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); this.$node.on("mouseover", this.selectors.selectable, function() { that.setCursor($(this)); }); this.$node.on("mouseleave", function() { that._removeCursor(); }); _.each(this.datasets, function(dataset) { dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); }); return this; }, isOpen: function isOpen() { return this.$node.hasClass(this.classes.open); }, open: function open() { this.$node.scrollTop(0); this.$node.addClass(this.classes.open); }, close: function close() { this.$node.attr("aria-expanded", false); this.$node.removeClass(this.classes.open); this._removeCursor(); }, setLanguageDirection: function setLanguageDirection(dir) { this.$node.attr("dir", dir); }, selectableRelativeToCursor: function selectableRelativeToCursor(delta) { var $selectables, $oldCursor, oldIndex, newIndex; $oldCursor = this.getActiveSelectable(); $selectables = this._getSelectables(); oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1; newIndex = oldIndex + delta; newIndex = (newIndex + 1) % ($selectables.length + 1) - 1; newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex; return newIndex === -1 ? null : $selectables.eq(newIndex); }, setCursor: function setCursor($selectable) { this._removeCursor(); if ($selectable = $selectable && $selectable.first()) { $selectable.addClass(this.classes.cursor); this._ensureVisible($selectable); } }, getSelectableData: function getSelectableData($el) { return $el && $el.length ? Dataset.extractData($el) : null; }, getActiveSelectable: function getActiveSelectable() { var $selectable = this._getSelectables().filter(this.selectors.cursor).first(); return $selectable.length ? $selectable : null; }, getTopSelectable: function getTopSelectable() { var $selectable = this._getSelectables().first(); return $selectable.length ? $selectable : null; }, update: function update(query) { var isValidUpdate = query !== this.query; if (isValidUpdate) { this.query = query; _.each(this.datasets, updateDataset); } return isValidUpdate; function updateDataset(dataset) { dataset.update(query); } }, empty: function empty() { _.each(this.datasets, clearDataset); this.query = null; this.$node.addClass(this.classes.empty); function clearDataset(dataset) { dataset.clear(); } }, destroy: function destroy() { this.$node.off(".tt"); this.$node = $("
"); _.each(this.datasets, destroyDataset); function destroyDataset(dataset) { dataset.destroy(); } } }); return Menu; }(); var Status = function() { "use strict"; function Status(options) { this.$el = $("", { role: "status", "aria-live": "polite" }).css({ position: "absolute", padding: "0", border: "0", height: "1px", width: "1px", "margin-bottom": "-1px", "margin-right": "-1px", overflow: "hidden", clip: "rect(0 0 0 0)", "white-space": "nowrap" }); options.$input.after(this.$el); _.each(options.menu.datasets, _.bind(function(dataset) { if (dataset.onSync) { dataset.onSync("rendered", _.bind(this.update, this)); dataset.onSync("cleared", _.bind(this.cleared, this)); } }, this)); } _.mixin(Status.prototype, { update: function update(event, suggestions) { var length = suggestions.length; var words; if (length === 1) { words = { result: "result", is: "is" }; } else { words = { result: "results", is: "are" }; } this.$el.text(length + " " + words.result + " " + words.is + " available, use up and down arrow keys to navigate."); }, cleared: function() { this.$el.text(""); } }); return Status; }(); var DefaultMenu = function() { "use strict"; var s = Menu.prototype; function DefaultMenu() { Menu.apply(this, [].slice.call(arguments, 0)); } _.mixin(DefaultMenu.prototype, Menu.prototype, { open: function open() { !this._allDatasetsEmpty() && this._show(); return s.open.apply(this, [].slice.call(arguments, 0)); }, close: function close() { this._hide(); return s.close.apply(this, [].slice.call(arguments, 0)); }, _onRendered: function onRendered() { if (this._allDatasetsEmpty()) { this._hide(); } else { this.isOpen() && this._show(); } return s._onRendered.apply(this, [].slice.call(arguments, 0)); }, _onCleared: function onCleared() { if (this._allDatasetsEmpty()) { this._hide(); } else { this.isOpen() && this._show(); } return s._onCleared.apply(this, [].slice.call(arguments, 0)); }, setLanguageDirection: function setLanguageDirection(dir) { this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl); return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0)); }, _hide: function hide() { this.$node.hide(); }, _show: function show() { this.$node.css("display", "block"); } }); return DefaultMenu; }(); var Typeahead = function() { "use strict"; function Typeahead(o, www) { var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged; o = o || {}; if (!o.input) { $.error("missing input"); } if (!o.menu) { $.error("missing menu"); } if (!o.eventBus) { $.error("missing event bus"); } www.mixin(this); this.eventBus = o.eventBus; this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; this.input = o.input; this.menu = o.menu; this.enabled = true; this.autoselect = !!o.autoselect; this.active = false; this.input.hasFocus() && this.activate(); this.dir = this.input.getLangDir(); this._hacks(); this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this); onFocused = c(this, "activate", "open", "_onFocused"); onBlurred = c(this, "deactivate", "_onBlurred"); onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed"); onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed"); onEscKeyed = c(this, "isActive", "_onEscKeyed"); onUpKeyed = c(this, "isActive", "open", "_onUpKeyed"); onDownKeyed = c(this, "isActive", "open", "_onDownKeyed"); onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed"); onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed"); onQueryChanged = c(this, "_openIfActive", "_onQueryChanged"); onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged"); this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this); } _.mixin(Typeahead.prototype, { _hacks: function hacks() { var $input, $menu; $input = this.input.$input || $("
"); $menu = this.menu.$node || $("
"); $input.on("blur.tt", function($e) { var active, isActive, hasActive; active = document.activeElement; isActive = $menu.is(active); hasActive = $menu.has(active).length > 0; if (_.isMsie() && (isActive || hasActive)) { $e.preventDefault(); $e.stopImmediatePropagation(); _.defer(function() { $input.focus(); }); } }); $menu.on("mousedown.tt", function($e) { $e.preventDefault(); }); }, _onSelectableClicked: function onSelectableClicked(type, $el) { this.select($el); }, _onDatasetCleared: function onDatasetCleared() { this._updateHint(); }, _onDatasetRendered: function onDatasetRendered(type, suggestions, async, dataset) { this._updateHint(); if (this.autoselect) { var cursorClass = this.selectors.cursor.substr(1); this.menu.$node.find(this.selectors.suggestion).first().addClass(cursorClass); } this.eventBus.trigger("render", suggestions, async, dataset); }, _onAsyncRequested: function onAsyncRequested(type, dataset, query) { this.eventBus.trigger("asyncrequest", query, dataset); }, _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) { this.eventBus.trigger("asynccancel", query, dataset); }, _onAsyncReceived: function onAsyncReceived(type, dataset, query) { this.eventBus.trigger("asyncreceive", query, dataset); }, _onFocused: function onFocused() { this._minLengthMet() && this.menu.update(this.input.getQuery()); }, _onBlurred: function onBlurred() { if (this.input.hasQueryChangedSinceLastFocus()) { this.eventBus.trigger("change", this.input.getQuery()); } }, _onEnterKeyed: function onEnterKeyed(type, $e) { var $selectable; if ($selectable = this.menu.getActiveSelectable()) { if (this.select($selectable)) { $e.preventDefault(); $e.stopPropagation(); } } else if (this.autoselect) { if (this.select(this.menu.getTopSelectable())) { $e.preventDefault(); $e.stopPropagation(); } } }, _onTabKeyed: function onTabKeyed(type, $e) { var $selectable; if ($selectable = this.menu.getActiveSelectable()) { this.select($selectable) && $e.preventDefault(); } else if (this.autoselect) { if ($selectable = this.menu.getTopSelectable()) { this.autocomplete($selectable) && $e.preventDefault(); } } }, _onEscKeyed: function onEscKeyed() { this.close(); }, _onUpKeyed: function onUpKeyed() { this.moveCursor(-1); }, _onDownKeyed: function onDownKeyed() { this.moveCursor(+1); }, _onLeftKeyed: function onLeftKeyed() { if (this.dir === "rtl" && this.input.isCursorAtEnd()) { this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); } }, _onRightKeyed: function onRightKeyed() { if (this.dir === "ltr" && this.input.isCursorAtEnd()) { this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); } }, _onQueryChanged: function onQueryChanged(e, query) { this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty(); }, _onWhitespaceChanged: function onWhitespaceChanged() { this._updateHint(); }, _onLangDirChanged: function onLangDirChanged(e, dir) { if (this.dir !== dir) { this.dir = dir; this.menu.setLanguageDirection(dir); } }, _openIfActive: function openIfActive() { this.isActive() && this.open(); }, _minLengthMet: function minLengthMet(query) { query = _.isString(query) ? query : this.input.getQuery() || ""; return query.length >= this.minLength; }, _updateHint: function updateHint() { var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match; $selectable = this.menu.getTopSelectable(); data = this.menu.getSelectableData($selectable); val = this.input.getInputValue(); if (data && !_.isBlankString(val) && !this.input.hasOverflow()) { query = Input.normalizeQuery(val); escapedQuery = _.escapeRegExChars(query); frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); match = frontMatchRegEx.exec(data.val); match && this.input.setHint(val + match[1]); } else { this.input.clearHint(); } }, isEnabled: function isEnabled() { return this.enabled; }, enable: function enable() { this.enabled = true; }, disable: function disable() { this.enabled = false; }, isActive: function isActive() { return this.active; }, activate: function activate() { if (this.isActive()) { return true; } else if (!this.isEnabled() || this.eventBus.before("active")) { return false; } else { this.active = true; this.eventBus.trigger("active"); return true; } }, deactivate: function deactivate() { if (!this.isActive()) { return true; } else if (this.eventBus.before("idle")) { return false; } else { this.active = false; this.close(); this.eventBus.trigger("idle"); return true; } }, isOpen: function isOpen() { return this.menu.isOpen(); }, open: function open() { if (!this.isOpen() && !this.eventBus.before("open")) { this.input.setAriaExpanded(true); this.menu.open(); this._updateHint(); this.eventBus.trigger("open"); } return this.isOpen(); }, close: function close() { if (this.isOpen() && !this.eventBus.before("close")) { this.input.setAriaExpanded(false); this.menu.close(); this.input.clearHint(); this.input.resetInputValue(); this.eventBus.trigger("close"); } return !this.isOpen(); }, setVal: function setVal(val) { this.input.setQuery(_.toStr(val)); }, getVal: function getVal() { return this.input.getQuery(); }, select: function select($selectable) { var data = this.menu.getSelectableData($selectable); if (data && !this.eventBus.before("select", data.obj, data.dataset)) { this.input.setQuery(data.val, true); this.eventBus.trigger("select", data.obj, data.dataset); this.close(); return true; } return false; }, autocomplete: function autocomplete($selectable) { var query, data, isValid; query = this.input.getQuery(); data = this.menu.getSelectableData($selectable); isValid = data && query !== data.val; if (isValid && !this.eventBus.before("autocomplete", data.obj, data.dataset)) { this.input.setQuery(data.val); this.eventBus.trigger("autocomplete", data.obj, data.dataset); return true; } return false; }, moveCursor: function moveCursor(delta) { var query, $candidate, data, suggestion, datasetName, cancelMove, id; query = this.input.getQuery(); $candidate = this.menu.selectableRelativeToCursor(delta); data = this.menu.getSelectableData($candidate); suggestion = data ? data.obj : null; datasetName = data ? data.dataset : null; id = $candidate ? $candidate.attr("id") : null; this.input.trigger("cursorchange", id); cancelMove = this._minLengthMet() && this.menu.update(query); if (!cancelMove && !this.eventBus.before("cursorchange", suggestion, datasetName)) { this.menu.setCursor($candidate); if (data) { if (typeof data.val === "string") { this.input.setInputValue(data.val); } } else { this.input.resetInputValue(); this._updateHint(); } this.eventBus.trigger("cursorchange", suggestion, datasetName); return true; } return false; }, destroy: function destroy() { this.input.destroy(); this.menu.destroy(); } }); return Typeahead; function c(ctx) { var methods = [].slice.call(arguments, 1); return function() { var args = [].slice.call(arguments); _.each(methods, function(method) { return ctx[method].apply(ctx, args); }); }; } }(); (function() { "use strict"; var old, keys, methods; old = $.fn.typeahead; keys = { www: "tt-www", attrs: "tt-attrs", typeahead: "tt-typeahead" }; methods = { initialize: function initialize(o, datasets) { var www; datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); o = o || {}; www = WWW(o.classNames); return this.each(attach); function attach() { var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, status, typeahead, MenuConstructor; _.each(datasets, function(d) { d.highlight = !!o.highlight; }); $input = $(this); $wrapper = $(www.html.wrapper); $hint = $elOrNull(o.hint); $menu = $elOrNull(o.menu); defaultHint = o.hint !== false && !$hint; defaultMenu = o.menu !== false && !$menu; defaultHint && ($hint = buildHintFromInput($input, www)); defaultMenu && ($menu = $(www.html.menu).css(www.css.menu)); $hint && $hint.val(""); $input = prepInput($input, www); if (defaultHint || defaultMenu) { $wrapper.css(www.css.wrapper); $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint); $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null); } MenuConstructor = defaultMenu ? DefaultMenu : Menu; eventBus = new EventBus({ el: $input }); input = new Input({ hint: $hint, input: $input, menu: $menu }, www); menu = new MenuConstructor({ node: $menu, datasets: datasets }, www); status = new Status({ $input: $input, menu: menu }); typeahead = new Typeahead({ input: input, menu: menu, eventBus: eventBus, minLength: o.minLength, autoselect: o.autoselect }, www); $input.data(keys.www, www); $input.data(keys.typeahead, typeahead); } }, isEnabled: function isEnabled() { var enabled; ttEach(this.first(), function(t) { enabled = t.isEnabled(); }); return enabled; }, enable: function enable() { ttEach(this, function(t) { t.enable(); }); return this; }, disable: function disable() { ttEach(this, function(t) { t.disable(); }); return this; }, isActive: function isActive() { var active; ttEach(this.first(), function(t) { active = t.isActive(); }); return active; }, activate: function activate() { ttEach(this, function(t) { t.activate(); }); return this; }, deactivate: function deactivate() { ttEach(this, function(t) { t.deactivate(); }); return this; }, isOpen: function isOpen() { var open; ttEach(this.first(), function(t) { open = t.isOpen(); }); return open; }, open: function open() { ttEach(this, function(t) { t.open(); }); return this; }, close: function close() { ttEach(this, function(t) { t.close(); }); return this; }, select: function select(el) { var success = false, $el = $(el); ttEach(this.first(), function(t) { success = t.select($el); }); return success; }, autocomplete: function autocomplete(el) { var success = false, $el = $(el); ttEach(this.first(), function(t) { success = t.autocomplete($el); }); return success; }, moveCursor: function moveCursoe(delta) { var success = false; ttEach(this.first(), function(t) { success = t.moveCursor(delta); }); return success; }, val: function val(newVal) { var query; if (!arguments.length) { ttEach(this.first(), function(t) { query = t.getVal(); }); return query; } else { ttEach(this, function(t) { t.setVal(_.toStr(newVal)); }); return this; } }, destroy: function destroy() { ttEach(this, function(typeahead, $input) { revert($input); typeahead.destroy(); }); return this; } }; $.fn.typeahead = function(method) { if (methods[method]) { return methods[method].apply(this, [].slice.call(arguments, 1)); } else { return methods.initialize.apply(this, arguments); } }; $.fn.typeahead.noConflict = function noConflict() { $.fn.typeahead = old; return this; }; function ttEach($els, fn) { $els.each(function() { var $input = $(this), typeahead; (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input); }); } function buildHintFromInput($input, www) { return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop({ readonly: true, required: false }).removeAttr("id name placeholder").removeClass("required").attr({ spellcheck: "false", tabindex: -1 }); } function prepInput($input, www) { $input.data(keys.attrs, { dir: $input.attr("dir"), autocomplete: $input.attr("autocomplete"), spellcheck: $input.attr("spellcheck"), style: $input.attr("style") }); $input.addClass(www.classes.input).attr({ spellcheck: false }); try { !$input.attr("dir") && $input.attr("dir", "auto"); } catch (e) {} return $input; } function getBackgroundStyles($el) { return { backgroundAttachment: $el.css("background-attachment"), backgroundClip: $el.css("background-clip"), backgroundColor: $el.css("background-color"), backgroundImage: $el.css("background-image"), backgroundOrigin: $el.css("background-origin"), backgroundPosition: $el.css("background-position"), backgroundRepeat: $el.css("background-repeat"), backgroundSize: $el.css("background-size") }; } function revert($input) { var www, $wrapper; www = $input.data(keys.www); $wrapper = $input.parent().filter(www.selectors.wrapper); _.each($input.data(keys.attrs), function(val, key) { _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); }); $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input); if ($wrapper.length) { $input.detach().insertAfter($wrapper); $wrapper.remove(); } } function $elOrNull(obj) { var isValid, $el; isValid = _.isJQuery(obj) || _.isElement(obj); $el = isValid ? $(obj).first() : []; return $el.length ? $el : null; } })(); }); ================================================ FILE: docs/docsets/Hero.docset/Contents/Resources/Documents/search.json ================================================ {"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV4viewSo6UIViewCSgvp":{"name":"view","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV11isAppearingSbvp":{"name":"isAppearing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV12isPresentingSbvp":{"name":"isPresenting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV20isInTabbarControllerSbvp":{"name":"isInTabbarController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV20isInNavbarControllerSbvp":{"name":"isInNavbarController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV9isMatchedSbvp":{"name":"isMatched","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV21isAncestorViewMatchedSbvp":{"name":"isAncestorViewMatched","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV11matchedViewSo6UIViewCSgvp":{"name":"matchedView","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV19matchedAncestorViewSo6UIViewC_AFtSgvp":{"name":"matchedAncestorView","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV18fromViewControllerSo06UIViewF0Cvp":{"name":"fromViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV16toViewControllerSo06UIViewF0Cvp":{"name":"toViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV21currentViewControllerSo06UIViewF0Cvp":{"name":"currentViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV19otherViewControllerSo06UIViewF0Cvp":{"name":"otherViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV05beginC0SayAA0A8ModifierCGSgvp":{"name":"beginState","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV20conditionalModifiersSaySbAA0A18ConditionalContextVc_SayAA0A8ModifierCGtGSgvp":{"name":"conditionalModifiers","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV8positionSo7CGPointVSgvp":{"name":"position","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV4sizeSo6CGSizeVSgvp":{"name":"size","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV9transformSo13CATransform3DVSgvp":{"name":"transform","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7opacitySfSgvp":{"name":"opacity","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12cornerRadius14CoreFoundation7CGFloatVSgvp":{"name":"cornerRadius","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV15backgroundColorSo10CGColorRefaSgvp":{"name":"backgroundColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV9zPosition14CoreFoundation7CGFloatVSgvp":{"name":"zPosition","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11anchorPointSo7CGPointVSgvp":{"name":"anchorPoint","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12contentsRectSo6CGRectVSgvp":{"name":"contentsRect","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13contentsScale14CoreFoundation7CGFloatVSgvp":{"name":"contentsScale","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11borderWidth14CoreFoundation7CGFloatVSgvp":{"name":"borderWidth","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11borderColorSo10CGColorRefaSgvp":{"name":"borderColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11shadowColorSo10CGColorRefaSgvp":{"name":"shadowColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13shadowOpacitySfSgvp":{"name":"shadowOpacity","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12shadowOffsetSo6CGSizeVSgvp":{"name":"shadowOffset","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12shadowRadius14CoreFoundation7CGFloatVSgvp":{"name":"shadowRadius","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV10shadowPathSo9CGPathRefaSgvp":{"name":"shadowPath","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13masksToBoundsSbSgvp":{"name":"masksToBounds","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13displayShadowSbvp":{"name":"displayShadow","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7overlaySo10CGColorRefa5color_14CoreFoundation7CGFloatV7opacitytSgvp":{"name":"overlay","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6spring14CoreFoundation7CGFloatV_AGtSgvp":{"name":"spring","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV5delaySdvp":{"name":"delay","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV8durationSdSgvp":{"name":"duration","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV14timingFunctionSo013CAMediaTimingE0CSgvp":{"name":"timingFunction","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV3arc14CoreFoundation7CGFloatVSgvp":{"name":"arc","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6sourceSSSgvp":{"name":"source","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7cascadeSd_AA16CascadeDirectionOSbtSgvp":{"name":"cascade","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV22ignoreSubviewModifiersSbSgvp":{"name":"ignoreSubviewModifiers","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV15coordinateSpaceAA0a10CoordinateE0OSgvp":{"name":"coordinateSpace","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV23useScaleBasedSizeChangeSbSgvp":{"name":"useScaleBasedSizeChange","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12snapshotTypeAA0a8SnapshotE0OSgvp":{"name":"snapshotType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7nonFadeSbvp":{"name":"nonFade","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12forceAnimateSbvp":{"name":"forceAnimate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6customSDySSypGSgvp":{"name":"custom","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6appendyyAA0A8ModifierCF":{"name":"append(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6append10contentsOfySayAA0A8ModifierCG_tF":{"name":"append(contentsOf:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateVyypSgSScip":{"name":"subscript(_:)","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:s25ExpressibleByArrayLiteralP05arrayD0x0cD7ElementQzd_tcfc":{"name":"init(arrayLiteral:)","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html":{"name":"HeroTargetState","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Structs/HeroConditionalContext.html":{"name":"HeroConditionalContext","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroTransitionDelegate.html#/s:4Hero0A18TransitionDelegateP04heroB0_9didUpdateyAA0aB0C_AA0aB5StateOtF":{"name":"heroTransition(_:didUpdate:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionDelegate"},"Protocols/HeroTransitionDelegate.html#/s:4Hero0A18TransitionDelegateP04heroB0_9didUpdateyAA0aB0C_SdtF":{"name":"heroTransition(_:didUpdate:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionDelegate"},"Protocols/HeroStringConvertible.html#/s:4Hero0A17StringConvertibleP4from4nodexSgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroStringConvertible"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroWillStartAnimatingFromViewController:":{"name":"heroWillStartAnimatingFrom(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidEndAnimatingFromViewController:":{"name":"heroDidEndAnimatingFrom(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidCancelAnimatingFromViewController:":{"name":"heroDidCancelAnimatingFrom(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroWillStartTransition":{"name":"heroWillStartTransition()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidEndTransition":{"name":"heroDidEndTransition()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidCancelTransition":{"name":"heroDidCancelTransition()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroWillStartAnimatingToViewController:":{"name":"heroWillStartAnimatingTo(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidEndAnimatingToViewController:":{"name":"heroDidEndAnimatingTo(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidCancelAnimatingToViewController:":{"name":"heroDidCancelAnimatingTo(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroProgressUpdateObserver.html#/s:4Hero0A22ProgressUpdateObserverP07heroDidcB08progressySd_tF":{"name":"heroDidUpdateProgress(progress:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroProgressUpdateObserver"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP4heroAA0A10TransitionCSgvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP10canAnimate4view9appearingSbSo6UIViewC_SbtF":{"name":"canAnimate(view:appearing:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP7animate9fromViews02toE0SdSaySo6UIViewCG_AItF":{"name":"animate(fromViews:toViews:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP5cleanyyF":{"name":"clean()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP6seekTo10timePassedySd_tF":{"name":"seekTo(timePassed:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP6resume10timePassed7reverseS2d_SbtF":{"name":"resume(timePassed:reverse:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP5apply5state2toyAA0A11TargetStateV_So6UIViewCtF":{"name":"apply(state:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP12changeTarget5state13isDestination2toyAA0aD5StateV_SbSo6UIViewCtF":{"name":"changeTarget(state:isDestination:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroPreprocessor.html#/s:4Hero0A12PreprocessorP4heroAA0A10TransitionCSgvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPreprocessor"},"Protocols/HeroPreprocessor.html#/s:4Hero0A12PreprocessorP7process9fromViews02toE0ySaySo6UIViewCG_AItF":{"name":"process(fromViews:toViews:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPreprocessor"},"Protocols/HeroCustomSnapshotView.html#/s:4Hero0A18CustomSnapshotViewP04heroC0So6UIViewCSgvp":{"name":"heroSnapshot","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCustomSnapshotView"},"Protocols/HeroCompatible.html#/s:4Hero0A10CompatibleP0B4TypeQa":{"name":"CompatibleType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCompatible"},"Protocols/HeroCompatible.html#/s:4Hero0A10CompatibleP4heroAA0A9ExtensionCy0B4TypeQzGvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCompatible"},"Protocols/HeroCompatible.html":{"name":"HeroCompatible","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroCustomSnapshotView.html":{"name":"HeroCustomSnapshotView","abstract":"\u003cp\u003eAllows a view to create their own custom snapshot when using \u003cstrong\u003eOptimized\u003c/strong\u003e snapshot\u003c/p\u003e"},"Protocols/HeroPreprocessor.html":{"name":"HeroPreprocessor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroAnimator.html":{"name":"HeroAnimator","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroProgressUpdateObserver.html":{"name":"HeroProgressUpdateObserver","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroViewControllerDelegate.html":{"name":"HeroViewControllerDelegate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroStringConvertible.html":{"name":"HeroStringConvertible","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroTransitionDelegate.html":{"name":"HeroTransitionDelegate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Functions.html#/s:4Hero2eeoiySbAA8ExprNodeC_ADtF":{"name":"==(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Extensions/HeroDebugView.html#/gestureRecognizerShouldBegin(_:)":{"name":"gestureRecognizerShouldBegin(_:)","parent_name":"HeroDebugView"},"Extensions/UINavigationController.html#/Operation":{"name":"Operation","parent_name":"UINavigationController"},"Extensions/String.html#/s:SS4HeroE5match5regexSS_SnySiGtSgSS_tF":{"name":"match(regex:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"String"},"Extensions/UITabBarController.html#/s:So18UITabBarControllerC4HeroE07heroTabB13AnimationTypeAC0d7DefaultgH0Ovp":{"name":"heroTabBarAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UITabBarController"},"Extensions/UITabBarController.html#/c:@CM@Hero@@objc(cs)UITabBarController(py)heroTabBarAnimationTypeString":{"name":"heroTabBarAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UITabBarController"},"Extensions/UINavigationController.html#/s:So22UINavigationControllerC4HeroE27heroNavigationAnimationTypeAC0c7DefaultfG0Ovp":{"name":"heroNavigationAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UINavigationController"},"Extensions/UINavigationController.html#/c:@CM@Hero@@objc(cs)UINavigationController(py)heroNavigationAnimationTypeString":{"name":"heroNavigationAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UINavigationController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE22heroModalAnimationTypeAC0c7DefaultfG0Ovp":{"name":"heroModalAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(py)heroModalAnimationTypeString":{"name":"heroModalAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(py)isHeroEnabled":{"name":"isHeroEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(im)ht_dismiss:":{"name":"ht_dismiss(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE015heroReplaceViewB04withyAB_tF":{"name":"heroReplaceViewController(with:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(im)hero_dismissViewController":{"name":"hero_dismissViewController()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(im)hero_unwindToRootViewController":{"name":"hero_unwindToRootViewController()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB0yyABF":{"name":"hero_unwindToViewController(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB012withSelectory10ObjectiveC0I0V_tF":{"name":"hero_unwindToViewController(withSelector:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB09withClassyyXlXp_tF":{"name":"hero_unwindToViewController(withClass:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB014withMatchBlockySbABXE_tF":{"name":"hero_unwindToViewController(withMatchBlock:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE016hero_replaceViewB04withyAB_tF":{"name":"hero_replaceViewController(with:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)heroID":{"name":"heroID","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)isHeroEnabled":{"name":"isHeroEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)isHeroEnabledForSubviews":{"name":"isHeroEnabledForSubviews","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/s:So6UIViewC4HeroE13heroModifiersSayAC0B8ModifierCGSgvp":{"name":"heroModifiers","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)heroModifierString":{"name":"heroModifierString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/CATransform3D.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"CATransform3D"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE6linearABvpZ":{"name":"linear","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE6easeInABvpZ":{"name":"easeIn","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE7easeOutABvpZ":{"name":"easeOut","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE9easeInOutABvpZ":{"name":"easeInOut","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE8standardABvpZ":{"name":"standard","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE12decelerationABvpZ":{"name":"deceleration","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE12accelerationABvpZ":{"name":"acceleration","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE5sharpABvpZ":{"name":"sharp","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE11easeOutBackABvpZ":{"name":"easeOutBack","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE4from4nameABSgSS_tFZ":{"name":"from(name:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html":{"name":"CAMediaTimingFunction"},"Extensions/CATransform3D.html":{"name":"CATransform3D"},"Extensions/UIView.html":{"name":"UIView"},"Extensions/UIViewController.html":{"name":"UIViewController"},"Extensions/UINavigationController.html":{"name":"UINavigationController"},"Extensions/UITabBarController.html":{"name":"UITabBarController"},"Extensions/String.html":{"name":"String"},"Extensions/HeroDebugView.html":{"name":"HeroDebugView"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO8possibleyA2CmF":{"name":"possible","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO8notifiedyA2CmF":{"name":"notified","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO8startingyA2CmF":{"name":"starting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO9animatingyA2CmF":{"name":"animating","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO10completingyA2CmF":{"name":"completing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroDefaultAnimationType/Strategy.html#/s:4Hero0A20DefaultAnimationTypeO8StrategyO16forceLeftToRightyA2EmF":{"name":"forceLeftToRight","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Strategy"},"Enums/HeroDefaultAnimationType/Strategy.html#/s:4Hero0A20DefaultAnimationTypeO8StrategyO16forceRightToLeftyA2EmF":{"name":"forceRightToLeft","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Strategy"},"Enums/HeroDefaultAnimationType/Strategy.html#/s:4Hero0A20DefaultAnimationTypeO8StrategyO13userInterfaceyA2EmF":{"name":"userInterface","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Strategy"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO4leftyA2EmF":{"name":"left","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO5rightyA2EmF":{"name":"right","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO2upyA2EmF":{"name":"up","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO4downyA2EmF":{"name":"down","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO4from4nodeAESgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO17leadingToTrailingAA07CascadeE0OvpZ":{"name":"leadingToTrailing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO17trailingToLeadingAA07CascadeE0OvpZ":{"name":"trailingToLeading","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO7leadingAEvpZ":{"name":"leading","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO8trailingAEvpZ":{"name":"trailing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html":{"name":"Direction","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType/Strategy.html":{"name":"Strategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4autoyA2CmF":{"name":"auto","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4pushyA2C9DirectionO_tcACmF":{"name":"push(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4pullyA2C9DirectionO_tcACmF":{"name":"pull(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO5coveryA2C9DirectionO_tcACmF":{"name":"cover(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO7uncoveryA2C9DirectionO_tcACmF":{"name":"uncover(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO5slideyA2C9DirectionO_tcACmF":{"name":"slide(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO9zoomSlideyA2C9DirectionO_tcACmF":{"name":"zoomSlide(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO6pageInyA2C9DirectionO_tcACmF":{"name":"pageIn(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO7pageOutyA2C9DirectionO_tcACmF":{"name":"pageOut(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4fadeyA2CmF":{"name":"fade","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4zoomyA2CmF":{"name":"zoom","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO7zoomOutyA2CmF":{"name":"zoomOut","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO8selectByyA2C_ACtcACmF":{"name":"selectBy(presenting:dismissing:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO11autoReverse10presentingA2C_tFZ":{"name":"autoReverse(presenting:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4noneyA2CmF":{"name":"none","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO5labelSSSgvp":{"name":"label","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4from4nodeACSgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11topToBottomyA2CmF":{"name":"topToBottom","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11bottomToTopyA2CmF":{"name":"bottomToTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11leftToRightyA2CmF":{"name":"leftToRight","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11rightToLeftyA2CmF":{"name":"rightToLeft","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO6radialyACSo7CGPointV_tcACmF":{"name":"radial(center:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO13inverseRadialyACSo7CGPointV_tcACmF":{"name":"inverseRadial(center:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO17leadingToTrailingACvpZ":{"name":"leadingToTrailing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO17trailingToLeadingACvpZ":{"name":"trailingToLeading","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/ParseError.html#/s:4Hero10ParseErrorO13unexpectTokenyA2CmF":{"name":"unexpectToken","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO17undefinedOperatoryACSScACmF":{"name":"undefinedOperator(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO15expectCharacteryACSJcACmF":{"name":"expectCharacter(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO16expectExpressionyA2CmF":{"name":"expectExpression","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO18expectArgumentListyA2CmF":{"name":"expectArgumentList","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO18expectFunctionNameyA2CmF":{"name":"expectFunctionName","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/Token.html#/s:4Hero5TokenO10identifieryACSS_SnySiGtcACmF":{"name":"identifier(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO6numberyACSf_SnySiGtcACmF":{"name":"number(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO10parensOpenyACSnySiGcACmF":{"name":"parensOpen(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO11parensCloseyACSnySiGcACmF":{"name":"parensClose(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO5commayACSnySiGcACmF":{"name":"comma(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO5otheryACSS_SnySiGtcACmF":{"name":"other(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/HeroViewOrderingStrategy.html#/s:4Hero0A20ViewOrderingStrategyO4autoyA2CmF":{"name":"auto","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewOrderingStrategy"},"Enums/HeroViewOrderingStrategy.html#/s:4Hero0A20ViewOrderingStrategyO06sourceB5OnTopyA2CmF":{"name":"sourceViewOnTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewOrderingStrategy"},"Enums/HeroViewOrderingStrategy.html#/s:4Hero0A20ViewOrderingStrategyO011destinationB5OnTopyA2CmF":{"name":"destinationViewOnTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewOrderingStrategy"},"Enums/HeroCoordinateSpace.html#/s:4Hero0A15CoordinateSpaceO6globalyA2CmF":{"name":"global","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCoordinateSpace"},"Enums/HeroCoordinateSpace.html#/s:4Hero0A15CoordinateSpaceO5localyA2CmF":{"name":"local","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCoordinateSpace"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO9optimizedyA2CmF":{"name":"optimized","abstract":"\u003cp\u003eWill optimize for different type of views","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO6normalyA2CmF":{"name":"normal","abstract":"\u003cp\u003esnapshotView(afterScreenUpdates:)\u003c/p\u003e","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO11layerRenderyA2CmF":{"name":"layerRender","abstract":"\u003cp\u003elayer.render(in: currentContext)\u003c/p\u003e","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO02noB0yA2CmF":{"name":"noSnapshot","abstract":"\u003cp\u003ewill not create snapshot. animate the view directly.","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html":{"name":"HeroSnapshotType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroCoordinateSpace.html":{"name":"HeroCoordinateSpace","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroViewOrderingStrategy.html":{"name":"HeroViewOrderingStrategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/Token.html":{"name":"Token","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/ParseError.html":{"name":"ParseError","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/CascadeDirection.html":{"name":"CascadeDirection","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroDefaultAnimationType.html":{"name":"HeroDefaultAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroTransitionState.html":{"name":"HeroTransitionState","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroDebugPlugin.html#/showOnTop":{"name":"showOnTop","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/animate(fromViews:toViews:)":{"name":"animate(fromViews:toViews:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/resume(timePassed:reverse:)":{"name":"resume(timePassed:reverse:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/clean()":{"name":"clean()","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/onDone()":{"name":"onDone()","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/onProcessSliderChanged(progress:)":{"name":"onProcessSliderChanged(progress:)","parent_name":"HeroDebugPlugin"},"Classes/Hero.html#/s:4HeroAAC6sharedAA0A10TransitionCvpZ":{"name":"shared","abstract":"\u003cp\u003eShared singleton object for controlling the transition\u003c/p\u003e","parent_name":"Hero"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC8delegateAA0aB8Delegate_pSgvp":{"name":"delegate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC16defaultAnimationAA0a7DefaultD4TypeOvp":{"name":"defaultAnimation","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC14containerColorSo7UIColorCvp":{"name":"containerColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC24isUserInteractionEnabledSbvp":{"name":"isUserInteractionEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC20viewOrderingStrategyAA0a4ViewdE0Ovp":{"name":"viewOrderingStrategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC33defaultAnimationDirectionStrategyAA0a7DefaultD4TypeO0F0Ovp":{"name":"defaultAnimationDirectionStrategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC5stateAA0aB5StateOvp":{"name":"state","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC15isTransitioningSbvp":{"name":"isTransitioning","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC12isPresentingSbvp":{"name":"isPresenting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC13transitioningSbvp":{"name":"transitioning","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC10presentingSbvp":{"name":"presenting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC9containerSo6UIViewCSgvp":{"name":"container","abstract":"\u003cp\u003econtainer we created to hold all animating views, will be a subview of the","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC16toViewControllerSo06UIViewE0CSgvp":{"name":"toViewController","abstract":"\u003cp\u003edestination view controller\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC18fromViewControllerSo06UIViewE0CSgvp":{"name":"fromViewController","abstract":"\u003cp\u003esource view controller\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC7contextAA0A7ContextCSgvp":{"name":"context","abstract":"\u003cp\u003econtext object holding transition informations\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC11interactiveSbvp":{"name":"interactive","abstract":"\u003cp\u003ewhether or not we are handling transition interactively\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC13totalDurationSdvp":{"name":"totalDuration","abstract":"\u003cp\u003emax duration needed by the animators\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC8progressSdvp":{"name":"progress","abstract":"\u003cp\u003eprogress of the current transition. 0 if no transition is happening\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@M@Hero@objc(cs)HeroTransition(im)init":{"name":"init()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC24observeForProgressUpdate8observeryAA0aeF8Observer_p_tF":{"name":"observeForProgressUpdate(observer:)","abstract":"\u003cp\u003eReceive callbacks on each animation frame.","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC7animateyyF":{"name":"animate()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC8complete8finishedySb_tF":{"name":"complete(finished:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC10transition4from2to2in10completionySo16UIViewControllerC_AJSo0H0CySbcSgtF":{"name":"transition(from:to:in:completion:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC6updateyy14CoreFoundation7CGFloatVF":{"name":"update(_:)","abstract":"\u003cp\u003eUpdate the progress for the interactive transition.\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC6finish7animateySb_tF":{"name":"finish(animate:)","abstract":"\u003cp\u003eFinish the interactive transition.","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC6cancel7animateySb_tF":{"name":"cancel(animate:)","abstract":"\u003cp\u003eCancel the interactive transition.","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC5apply9modifiers2toySayAA0A8ModifierCG_So6UIViewCtF":{"name":"apply(modifiers:to:)","abstract":"\u003cp\u003eOverride modifiers during an interactive animation.\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC12changeTarget9modifiers13isDestination2toySayAA0A8ModifierCG_SbSo6UIViewCtF":{"name":"changeTarget(modifiers:isDestination:to:)","abstract":"\u003cp\u003eOverride target state during an interactive animation.\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC5startyyF":{"name":"start()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:willShowViewController:animated:":{"name":"navigationController(_:willShow:animated:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:didShowViewController:animated:":{"name":"navigationController(_:didShow:animated:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:animationControllerForOperation:fromViewController:toViewController:":{"name":"navigationController(_:animationControllerFor:from:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:interactionControllerForAnimationController:":{"name":"navigationController(_:interactionControllerFor:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)tabBarController:shouldSelectViewController:":{"name":"tabBarController(_:shouldSelect:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)tabBarController:interactionControllerForAnimationController:":{"name":"tabBarController(_:interactionControllerFor:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)tabBarController:animationControllerForTransitionFromViewController:toViewController:":{"name":"tabBarController(_:animationControllerForTransitionFrom:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animationControllerForPresentedController:presentingController:sourceController:":{"name":"animationController(forPresented:presenting:source:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animationControllerForDismissedController:":{"name":"animationController(forDismissed:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)interactionControllerForDismissal:":{"name":"interactionControllerForDismissal(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)interactionControllerForPresentation:":{"name":"interactionControllerForPresentation(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animateTransition:":{"name":"animateTransition(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)transitionDuration:":{"name":"transitionDuration(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animationEnded:":{"name":"animationEnded(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(py)wantsInteractiveStart":{"name":"wantsInteractiveStart","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)startInteractiveTransition:":{"name":"startInteractiveTransition(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/Parser.html#/s:4Hero6ParserC6tokensACSayAA5TokenOG_tcfc":{"name":"init(tokens:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Parser"},"Classes/Parser.html#/s:4Hero6ParserC5parseSayAA8ExprNodeCGyKF":{"name":"parse()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Parser"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC9prototypeAA09PrototypeC0Cvp":{"name":"prototype","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC4bodyAA04ExprC0Cvp":{"name":"body","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC9prototype4bodyAcA09PrototypeC0C_AA04ExprC0Ctcfc":{"name":"init(prototype:body:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/PrototypeNode.html#/s:4Hero13PrototypeNodeC13argumentNamesSaySSGvp":{"name":"argumentNames","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"PrototypeNode"},"Classes/PrototypeNode.html#/s:4Hero13PrototypeNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"PrototypeNode"},"Classes/PrototypeNode.html#/s:4Hero13PrototypeNodeC4name13argumentNamesACSS_SaySSGtcfc":{"name":"init(name:argumentNames:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"PrototypeNode"},"Classes/CallNode.html#/s:4Hero8CallNodeC9argumentsSayAA04ExprC0CGvp":{"name":"arguments","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CallNode"},"Classes/CallNode.html#/s:4Hero8CallNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CallNode"},"Classes/CallNode.html#/s:4Hero8CallNodeC4name9argumentsACSS_SayAA04ExprC0CGtcfc":{"name":"init(name:arguments:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CallNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC3lhsAA04ExprD0Cvp":{"name":"lhs","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC3rhsAA04ExprD0Cvp":{"name":"rhs","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC4name3lhs3rhsACSS_AA04ExprD0CAHtcfc":{"name":"init(name:lhs:rhs:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/VariableNode.html#/s:4Hero12VariableNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"VariableNode"},"Classes/NumberNode.html#/s:4Hero10NumberNodeC5valueSfvp":{"name":"value","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"NumberNode"},"Classes/NumberNode.html#/s:4Hero10NumberNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"NumberNode"},"Classes/NumberNode.html#/s:4Hero10NumberNodeC5valueACSf_tcfc":{"name":"init(value:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"NumberNode"},"Classes/ExprNode.html#/s:4Hero8ExprNodeC5rangeSnySiGvp":{"name":"range","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ExprNode"},"Classes/ExprNode.html#/s:4Hero8ExprNodeC4nameSSvp":{"name":"name","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ExprNode"},"Classes/ExprNode.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"ExprNode"},"Classes/ExprNode.html#/s:4Hero8ExprNodeC4nameACSS_tcfc":{"name":"init(name:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ExprNode"},"Classes/Lexer.html#/s:4Hero5LexerC5inputACSS_tcfc":{"name":"init(input:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Lexer"},"Classes/Lexer.html#/s:4Hero5LexerC8tokenizeSayAA5TokenOGyF":{"name":"tokenize()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Lexer"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC4heroAA0A10TransitionCSgvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7contextAA0A7ContextCSgvp":{"name":"context","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC23requirePerFrameCallbackSbvp":{"name":"requirePerFrameCallback","abstract":"\u003cp\u003eDetermines whether or not to receive \u003ccode\u003eseekTo\u003c/code\u003e callback on every frame.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/c:@M@Hero@objc(cs)HeroPlugin(im)init":{"name":"init()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7process9fromViews02toE0ySaySo6UIViewCG_AItF":{"name":"process(fromViews:toViews:)","abstract":"\u003cp\u003eCalled before any animation.","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC10canAnimate4view9appearingSbSo6UIViewC_SbtF":{"name":"canAnimate(view:appearing:)","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7animate9fromViews02toE0SdSaySo6UIViewCG_AItF":{"name":"animate(fromViews:toViews:)","abstract":"\u003cp\u003ePerform the animation.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC5cleanyyF":{"name":"clean()","abstract":"\u003cp\u003eCalled when all animations are completed.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC6seekTo10timePassedySd_tF":{"name":"seekTo(timePassed:)","abstract":"\u003cp\u003eFor supporting interactive animation only.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC6resume10timePassed7reverseS2d_SbtF":{"name":"resume(timePassed:reverse:)","abstract":"\u003cp\u003eFor supporting interactive animation only.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC5apply5state2toyAA0A11TargetStateV_So6UIViewCtF":{"name":"apply(state:to:)","abstract":"\u003cp\u003eFor supporting interactive animation only.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC12changeTarget5state13isDestination2toyAA0aD5StateV_SbSo6UIViewCtF":{"name":"changeTarget(state:isDestination:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC9isEnabledSbvpZ":{"name":"isEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC6enableyyFZ":{"name":"enable()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7disableyyFZ":{"name":"disable()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13applyFunctionACyAA0A11TargetStateVzc_tcfc":{"name":"init(applyFunction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9beginWithyACSayACGFZ":{"name":"beginWith(_:)","abstract":"\u003cp\u003eApply modifiers directly to the view at the start of the transition.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9beginWith9modifiersACSayACG_tFZ":{"name":"beginWith(modifiers:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9beginWithyA2Cd_tFZ":{"name":"beginWith(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC24useGlobalCoordinateSpaceACvpZ":{"name":"useGlobalCoordinateSpace","abstract":"\u003cp\u003eUse global coordinate space.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC22ignoreSubviewModifiersACvpZ":{"name":"ignoreSubviewModifiers","abstract":"\u003cp\u003eignore all heroModifiers attributes for a view\u0026rsquo;s direct subviews.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC22ignoreSubviewModifiers9recursiveACSb_tFZ":{"name":"ignoreSubviewModifiers(recursive:)","abstract":"\u003cp\u003eignore all heroModifiers attributes for a view\u0026rsquo;s subviews.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC20useOptimizedSnapshotACvpZ":{"name":"useOptimizedSnapshot","abstract":"\u003cp\u003eWill create snapshot optimized for different view type.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC17useNormalSnapshotACvpZ":{"name":"useNormalSnapshot","abstract":"\u003cp\u003eCreate snapshot using snapshotView(afterScreenUpdates:).\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC22useLayerRenderSnapshotACvpZ":{"name":"useLayerRenderSnapshot","abstract":"\u003cp\u003eCreate snapshot using layer.render(in: currentContext).","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13useNoSnapshotACvpZ":{"name":"useNoSnapshot","abstract":"\u003cp\u003eForce Hero to not create any snapshot when animating this view.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12forceAnimateACvpZ":{"name":"forceAnimate","abstract":"\u003cp\u003eForce the view to animate.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC23useScaleBasedSizeChangeACvpZ":{"name":"useScaleBasedSizeChange","abstract":"\u003cp\u003eForce Hero use scale based size animation. This will convert all .size modifier into .scale modifier.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4from4nodeACSgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4fadeACvpZ":{"name":"fade","abstract":"\u003cp\u003eFade the view during transition\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12forceNonFadeACvpZ":{"name":"forceNonFade","abstract":"\u003cp\u003eForce don\u0026rsquo;t fade view during transition\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC8positionyACSo7CGPointVFZ":{"name":"position(_:)","abstract":"\u003cp\u003eSet the position for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4sizeyACSo6CGSizeVFZ":{"name":"size(_:)","abstract":"\u003cp\u003eSet the size for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9transformyACSo13CATransform3DVFZ":{"name":"transform(_:)","abstract":"\u003cp\u003eSet the transform for the view to animate from/to. Will override previous perspective, scale, translate, \u0026amp; rotate modifiers\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11perspectiveyAC14CoreFoundation7CGFloatVFZ":{"name":"perspective(_:)","abstract":"\u003cp\u003eSet the perspective on the transform. use in combination with the rotate modifier.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC5scale1x1y1zAC14CoreFoundation7CGFloatV_A2JtFZ":{"name":"scale(x:y:z:)","abstract":"\u003cp\u003eScale 3d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC5scaleyAC14CoreFoundation7CGFloatVFZ":{"name":"scale(_:)","abstract":"\u003cp\u003eScale in x \u0026amp; y axis\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9translate1x1y1zAC14CoreFoundation7CGFloatV_A2JtFZ":{"name":"translate(x:y:z:)","abstract":"\u003cp\u003eTranslate 3d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9translate_1zACSo7CGPointV_14CoreFoundation7CGFloatVtFZ":{"name":"translate(_:z:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6rotate1x1y1zAC14CoreFoundation7CGFloatV_A2JtFZ":{"name":"rotate(x:y:z:)","abstract":"\u003cp\u003eRotate 3d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6rotate_1zACSo7CGPointV_14CoreFoundation7CGFloatVtFZ":{"name":"rotate(_:z:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6rotateyAC14CoreFoundation7CGFloatVFZ":{"name":"rotate(_:)","abstract":"\u003cp\u003eRotate 2d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC15backgroundColoryACSo7UIColorCFZ":{"name":"backgroundColor(_:)","abstract":"\u003cp\u003eSet the backgroundColor for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11borderColoryACSo7UIColorCFZ":{"name":"borderColor(_:)","abstract":"\u003cp\u003eSet the borderColor for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11shadowColoryACSo7UIColorCFZ":{"name":"shadowColor(_:)","abstract":"\u003cp\u003eSet the shadowColor for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7overlay5color7opacityACSo7UIColorC_14CoreFoundation7CGFloatVtFZ":{"name":"overlay(color:opacity:)","abstract":"\u003cp\u003eCreate an overlay on the animating view.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7opacityyAC14CoreFoundation7CGFloatVFZ":{"name":"opacity(_:)","abstract":"\u003cp\u003eSet the opacity for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12cornerRadiusyAC14CoreFoundation7CGFloatVFZ":{"name":"cornerRadius(_:)","abstract":"\u003cp\u003eSet the cornerRadius for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9zPositionyAC14CoreFoundation7CGFloatVFZ":{"name":"zPosition(_:)","abstract":"\u003cp\u003eSet the zPosition for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12contentsRectyACSo6CGRectVFZ":{"name":"contentsRect(_:)","abstract":"\u003cp\u003eSet the contentsRect for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13contentsScaleyAC14CoreFoundation7CGFloatVFZ":{"name":"contentsScale(_:)","abstract":"\u003cp\u003eSet the contentsScale for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11borderWidthyAC14CoreFoundation7CGFloatVFZ":{"name":"borderWidth(_:)","abstract":"\u003cp\u003eSet the borderWidth for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13shadowOpacityyAC14CoreFoundation7CGFloatVFZ":{"name":"shadowOpacity(_:)","abstract":"\u003cp\u003eSet the shadowOpacity for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12shadowOffsetyACSo6CGSizeVFZ":{"name":"shadowOffset(_:)","abstract":"\u003cp\u003eSet the shadowOffset for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12shadowRadiusyAC14CoreFoundation7CGFloatVFZ":{"name":"shadowRadius(_:)","abstract":"\u003cp\u003eSet the shadowRadius for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC10shadowPathyACSo9CGPathRefaFZ":{"name":"shadowPath(_:)","abstract":"\u003cp\u003eSet the shadowPath for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13masksToBoundsyACSbFZ":{"name":"masksToBounds(_:)","abstract":"\u003cp\u003eSet the masksToBounds for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC8durationyACSdFZ":{"name":"duration(_:)","abstract":"\u003cp\u003eSets the duration of the animation for a given view. If not used, Hero will use determine the duration based on the distance and size changes.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC20durationMatchLongestACvpZ":{"name":"durationMatchLongest","abstract":"\u003cp\u003eSets the duration of the animation for a given view to match the longest animation of the transition.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC5delayyACSdFZ":{"name":"delay(_:)","abstract":"\u003cp\u003eSets the delay of the animation for a given view.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC14timingFunctionyACSo013CAMediaTimingD0CFZ":{"name":"timingFunction(_:)","abstract":"\u003cp\u003eSets the timing function of the animation for a given view. If not used, Hero will use determine the timing function based on whether or not the view is entering or exiting the screen.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6spring9stiffness7dampingAC14CoreFoundation7CGFloatV_AItFZ":{"name":"spring(stiffness:damping:)","abstract":"\u003cp\u003e(iOS 9+) Use spring animation with custom stiffness \u0026amp; damping. The duration will be automatically calculated. Will be ignored if arc, timingFunction, or duration is set.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6source6heroIDACSS_tFZ":{"name":"source(heroID:)","abstract":"\u003cp\u003eTransition from/to the state of the view with matching heroID","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC3arcACvpZ":{"name":"arc","abstract":"\u003cp\u003eWorks in combination with position modifier to apply a natural curve when moving to the destination.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC3arc9intensityAC14CoreFoundation7CGFloatV_tFZ":{"name":"arc(intensity:)","abstract":"\u003cp\u003eWorks in combination with position modifier to apply a natural curve when moving to the destination.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7cascadeACvpZ":{"name":"cascade","abstract":"\u003cp\u003eCascade applys increasing delay modifiers to subviews\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7cascade5delta9direction17delayMatchedViewsACSd_AA16CascadeDirectionOSbtFZ":{"name":"cascade(delta:direction:delayMatchedViews:)","abstract":"\u003cp\u003eCascade applys increasing delay modifiers to subviews\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4whenyACSbAA0A18ConditionalContextVc_SayACGtFZ":{"name":"when(_:_:)","abstract":"\u003cp\u003eApply modifiers only if the condition return true.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4whenyACSbAA0A18ConditionalContextVc_ACdtFZ":{"name":"when(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11whenMatchedyA2Cd_tFZ":{"name":"whenMatched(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC14whenPresentingyA2Cd_tFZ":{"name":"whenPresenting(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC14whenDismissingyA2Cd_tFZ":{"name":"whenDismissing(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13whenAppearingyA2Cd_tFZ":{"name":"whenAppearing(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC16whenDisappearingyA2Cd_tFZ":{"name":"whenDisappearing(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroContext.html#/s:4Hero0A7ContextC9containerSo6UIViewCvp":{"name":"container","abstract":"\u003cp\u003eThe container holding all of the animating views\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC9fromViewsSaySo6UIViewCGvp":{"name":"fromViews","abstract":"\u003cp\u003eA flattened list of all views from source ViewController\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC7toViewsSaySo6UIViewCGvp":{"name":"toViews","abstract":"\u003cp\u003eA flattened list of all views from destination ViewController\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC10sourceView3forSo6UIViewCSgSS_tF":{"name":"sourceView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC15destinationView3forSo6UIViewCSgSS_tF":{"name":"destinationView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC10pairedView3forSo6UIViewCSgAG_tF":{"name":"pairedView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC12snapshotView3forSo6UIViewCAG_tF":{"name":"snapshotView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextCyAA0A11TargetStateVSgSo6UIViewCcip":{"name":"subscript(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC5cleanyyF":{"name":"clean()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC4hide4viewySo6UIViewC_tF":{"name":"hide(view:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC6unhide4viewySo6UIViewC_tF":{"name":"unhide(view:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionC4basexvp":{"name":"base","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE2idSSSgvp":{"name":"id","abstract":"\u003cp\u003e\u003cstrong\u003eID\u003c/strong\u003e is the identifier for the view. When doing a transition between two view controllers,","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE9isEnabledSbvp":{"name":"isEnabled","abstract":"\u003cp\u003e\u003cstrong\u003eisEnabled\u003c/strong\u003e allows to specify whether a view and its subviews should be consider for animations.","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE20isEnabledForSubviewsSbvp":{"name":"isEnabledForSubviews","abstract":"\u003cp\u003e\u003cstrong\u003eisEnabledForSubviews\u003c/strong\u003e allows to specify whether a view\u0026rsquo;s subviews should be consider for animations.","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE9modifiersSayAA0A8ModifierCGSgvp":{"name":"modifiers","abstract":"\u003cp\u003eUse \u003cstrong\u003emodifiers\u003c/strong\u003e to specify animations alongside the main transition. Checkout \u003ccode\u003eHeroModifier.swift\u003c/code\u003e for available modifiers.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE14modifierStringSSSgvp":{"name":"modifierString","abstract":"\u003cp\u003emodifierString** provides another way to set \u003cstrong\u003emodifiers\u003c/strong\u003e. It can be assigned through storyboard.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE18modalAnimationTypeAA0a7DefaultfG0Ovp":{"name":"modalAnimationType","abstract":"\u003cp\u003edefault hero animation type for presenting \u0026amp; dismissing modally\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE24modalAnimationTypeStringSSSgvp":{"name":"modalAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE9isEnabledSbvp":{"name":"isEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo22UINavigationControllerCRbzlE23navigationAnimationTypeAA0a7DefaultfG0Ovp":{"name":"navigationAnimationType","abstract":"\u003cp\u003edefault hero animation type for push and pop within the navigation controller\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo22UINavigationControllerCRbzlE29navigationAnimationTypeStringSSSgvp":{"name":"navigationAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo18UITabBarControllerCRbzlE03tabD13AnimationTypeAA0a7DefaultgH0Ovp":{"name":"tabBarAnimationType","abstract":"\u003cp\u003edefault hero animation type for switching tabs within the tab bar controller\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo18UITabBarControllerCRbzlE03tabD19AnimationTypeStringSSSgvp":{"name":"tabBarAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE011dismissViewD010completionyyycSg_tF":{"name":"dismissViewController(completion:)","abstract":"\u003cp\u003eDismiss the current view controller with animation. Will perform a navigationController.popViewController","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE016unwindToRootViewD0yyF":{"name":"unwindToRootViewController()","abstract":"\u003cp\u003eUnwind to the root view controller using Hero\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD0yyAEF":{"name":"unwindToViewController(_:)","abstract":"\u003cp\u003eUnwind to a specific view controller using Hero\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD012withSelectory10ObjectiveC0I0V_tF":{"name":"unwindToViewController(withSelector:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD09withClassyyXlXp_tF":{"name":"unwindToViewController(withClass:)","abstract":"\u003cp\u003eUnwind to a view controller with given class using Hero\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD014withMatchBlockySbAEXE_tF":{"name":"unwindToViewController(withMatchBlock:)","abstract":"\u003cp\u003eUnwind to a view controller that the matchBlock returns true on.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE011replaceViewD04with10completionyAE_yycSgtF":{"name":"replaceViewController(with:completion:)","abstract":"\u003cp\u003eReplace the current view controller with another VC on the navigation/modal/root view of UIWindow stack.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC9showOnTopSbvpZ":{"name":"showOnTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC7animate9fromViews02toF0SdSaySo6UIViewCG_AItF":{"name":"animate(fromViews:toViews:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC6resume10timePassed7reverseS2d_SbtF":{"name":"resume(timePassed:reverse:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC5cleanyyF":{"name":"clean()","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC6onDoneyyF":{"name":"onDone()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC22onProcessSliderChanged8progressySf_tF":{"name":"onProcessSliderChanged(progress:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html":{"name":"HeroDebugPlugin"},"Classes/HeroExtension.html":{"name":"HeroExtension","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroContext.html":{"name":"HeroContext","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroModifier.html":{"name":"HeroModifier","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroPlugin.html":{"name":"HeroPlugin","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/Lexer.html":{"name":"Lexer","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/ExprNode.html":{"name":"ExprNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/NumberNode.html":{"name":"NumberNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/VariableNode.html":{"name":"VariableNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/BinaryOpNode.html":{"name":"BinaryOpNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/CallNode.html":{"name":"CallNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/PrototypeNode.html":{"name":"PrototypeNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/FunctionNode.html":{"name":"FunctionNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/Parser.html":{"name":"Parser","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroTransition.html":{"name":"HeroTransition","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/Hero.html":{"name":"Hero","abstract":"\u003ch3 id='the-singleton-class-object-for-controlling-interactive-transitions' class='heading'\u003eThe singleton class/object for controlling interactive transitions.\u003c/h3\u003e"},"Classes.html":{"name":"Classes","abstract":"\u003cp\u003eThe following classes are available globally.\u003c/p\u003e"},"Enums.html":{"name":"Enumerations","abstract":"\u003cp\u003eThe following enumerations are available globally.\u003c/p\u003e"},"Extensions.html":{"name":"Extensions","abstract":"\u003cp\u003eThe following extensions are available globally.\u003c/p\u003e"},"Functions.html":{"name":"Functions","abstract":"\u003cp\u003eThe following functions are available globally.\u003c/p\u003e"},"Protocols.html":{"name":"Protocols","abstract":"\u003cp\u003eThe following protocols are available globally.\u003c/p\u003e"},"Structs.html":{"name":"Structures","abstract":"\u003cp\u003eThe following structures are available globally.\u003c/p\u003e"}} ================================================ FILE: docs/index.html ================================================ Hero Reference

Hero 1.6.4 Docs (24% documented)

GitHub View on GitHub

Dash Install in Dash

Hero is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit’s cumbersome transition APIs—making custom transitions an easy task for developers.

Carthage compatible Accio supported codecov Version License Xcode 10.0+ iOS 10.0+ Swift 4.0+ 中文 README Donate

Unit Test Swift PM

      

Hero is similar to Keynote’s Magic Move. It checks the heroID property on all source and destination views. Every matched view pair is then automatically transitioned from its old state to its new state.

Hero can also construct animations for unmatched views. It is easy to define these animations via the heroModifiers property. Hero will run these animations alongside the Magic Move animations. All of these animations can be interactively controlled by user gestures.

At view controller level, Hero provides several template transitions that you can set through heroModalAnimationType, heroNavigationAnimationType, and heroTabBarAnimationType. These can be used as the foundation of your custom transitions. Combine with heroID & heroModifiers to make your own unique transitions.

      

By default, Hero provides dynamic duration based on the Material Design Motion Guide. Duration is automatically determined by changes to distance and size—saving you the hassle, while providing consistent and delightful animations.

Hero doesn’t make any assumptions about how the view is built or structured. It won’t modify any of your views’ states other than hiding them during the animation. This makes it work with Auto Layout, programmatic layout, UICollectionView (without modifying its layout object), UITableView, UINavigationController, UITabBarController, etc…

Usage Example 1

View Controller 1

redView.hero.id = "ironMan"
blackView.hero.id = "batMan"

View Controller 2

self.hero.isEnabled = true
redView.hero.id = "ironMan"
blackView.hero.id = "batMan"
whiteView.hero.modifiers = [.translate(y:100)]

Usage Example 2

View Controller 1

greyView.hero.id = "skyWalker"

View Controller 2

self.hero.isEnabled = true
greyView.hero.id = "skyWalker"

// collectionView is the parent view of all red cells
collectionView.hero.modifiers = [.cascade]
for cell in redCells {
    cell.hero.modifiers = [.fade, .scale(0.5)]
}

You can do these in the storyboard too!

Installation

CocoaPods

Add the following entry to your Podfile:

pod 'Hero'

Then run pod install.

Don’t forget to import Hero in every file you’d like to use Hero.

Carthage

Add the following entry to your Cartfile:

github "HeroTransitions/Hero"

Then run carthage update.

If this is your first time using Carthage in the project, you’ll need to go through some additional steps as explained over at Carthage.

Accio

Add the following to your Package.swift:

.package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.4.0")),

Next, add Hero to your App targets dependencies like so:

.target(
    name: "App",
    dependencies: [
        "Hero",
    ]
),

Then run accio update.

Swift Package Manager

To integrate using Apple’s Swift package manager, add the following as a dependency to your Package.swift:

.package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.3.0"))

and then specify "Hero" as a dependency of the Target in which you wish to use Hero. Here’s an example PackageDescription:

// swift-tools-version:4.0
import PackageDescription

let package = Package(
    name: "MyPackage",
    products: [
        .library(
            name: "MyPackage",
            targets: ["MyPackage"]),
    ],
    dependencies: [
        .package(url: "https://github.com/HeroTransitions/Hero.git", .upToNextMajor(from: "1.6.3"))
    ],
    targets: [
        .target(
            name: "MyPackage",
            dependencies: ["Hero"])
    ]
)

Manually

  • Drag the Sources folder anywhere in your project.

Documentations

Checkout the WIKI PAGES (Usage Guide) for documentations.

For more up-to-date ones, please see the header-doc. (use alt+click in Xcode)

Dash compatible API docs: https://HeroTransitions.github.io/Hero/

Interactive Transition Tutorials

Interactive transitions with Hero (Part 1)

FAQ

Not able to use Hero transition even when self.hero.isEnabled is set to true

Make sure that you have also enabled self.hero.isEnabled on the navigation controller if you are doing a push/pop inside the navigation controller.

Views being covered by another matched view during the transition

Matched views use global coordinate space while unmatched views use local coordinate space by default. Local coordinate spaced views might be covered by other global coordinate spaced views. To solve this, use the useGlobalCoordinateSpace modifier on the views being covered. Checkout Coordinate Space Wiki page for details.

Push animation is shown along side my custom animation

This is the default animation for navigation controller provided by Hero. To disable the push animation, set self.hero.navigationAnimationType to .fade or .none on the navigation controller.

How do I use a different default animation when dismissing

You can use the animation type .selectBy(presenting:dismissing) to specify a different default animation for dismiss.

For example:

    self.hero.modalAnimationType = .selectBy(presenting:.zoom, dismissing:.zoomOut)

Contribute

We welcome any contributions. Please read the Contribution Guide.

================================================ FILE: docs/js/jazzy.js ================================================ // Jazzy - https://github.com/realm/jazzy // Copyright Realm Inc. // SPDX-License-Identifier: MIT window.jazzy = {'docset': false} if (typeof window.dash != 'undefined') { document.documentElement.className += ' dash' window.jazzy.docset = true } if (navigator.userAgent.match(/xcode/i)) { document.documentElement.className += ' xcode' window.jazzy.docset = true } function toggleItem($link, $content) { var animationDuration = 300; $link.toggleClass('token-open'); $content.slideToggle(animationDuration); } function itemLinkToContent($link) { return $link.parent().parent().next(); } // On doc load + hash-change, open any targetted item function openCurrentItemIfClosed() { if (window.jazzy.docset) { return; } var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token'); $content = itemLinkToContent($link); if ($content.is(':hidden')) { toggleItem($link, $content); } } $(openCurrentItemIfClosed); $(window).on('hashchange', openCurrentItemIfClosed); // On item link ('token') click, toggle its discussion $('.token').on('click', function(event) { if (window.jazzy.docset) { return; } var $link = $(this); toggleItem($link, itemLinkToContent($link)); // Keeps the document from jumping to the hash. var href = $link.attr('href'); if (history.pushState) { history.pushState({}, '', href); } else { location.hash = href; } event.preventDefault(); }); // Clicks on links to the current, closed, item need to open the item $("a:not('.token')").on('click', function() { if (location == this.href) { openCurrentItemIfClosed(); } }); // KaTeX rendering if ("katex" in window) { $($('.math').each( (_, element) => { katex.render(element.textContent, element, { displayMode: $(element).hasClass('m-block'), throwOnError: false, trust: true }); })) } ================================================ FILE: docs/js/jazzy.search.js ================================================ // Jazzy - https://github.com/realm/jazzy // Copyright Realm Inc. // SPDX-License-Identifier: MIT $(function(){ var $typeahead = $('[data-typeahead]'); var $form = $typeahead.parents('form'); var searchURL = $form.attr('action'); function displayTemplate(result) { return result.name; } function suggestionTemplate(result) { var t = '
'; t += '' + result.name + ''; if (result.parent_name) { t += '' + result.parent_name + ''; } t += '
'; return t; } $typeahead.one('focus', function() { $form.addClass('loading'); $.getJSON(searchURL).then(function(searchData) { const searchIndex = lunr(function() { this.ref('url'); this.field('name'); this.field('abstract'); for (const [url, doc] of Object.entries(searchData)) { this.add({url: url, name: doc.name, abstract: doc.abstract}); } }); $typeahead.typeahead( { highlight: true, minLength: 3, autoselect: true }, { limit: 10, display: displayTemplate, templates: { suggestion: suggestionTemplate }, source: function(query, sync) { const lcSearch = query.toLowerCase(); const results = searchIndex.query(function(q) { q.term(lcSearch, { boost: 100 }); q.term(lcSearch, { boost: 10, wildcard: lunr.Query.wildcard.TRAILING }); }).map(function(result) { var doc = searchData[result.ref]; doc.url = result.ref; return doc; }); sync(results); } } ); $form.removeClass('loading'); $typeahead.trigger('focus'); }); }); var baseURL = searchURL.slice(0, -"search.json".length); $typeahead.on('typeahead:select', function(e, result) { window.location = baseURL + result.url; }); }); ================================================ FILE: docs/js/typeahead.jquery.js ================================================ /*! * typeahead.js 1.3.1 * https://github.com/corejavascript/typeahead.js * Copyright 2013-2020 Twitter, Inc. and other contributors; Licensed MIT */ (function(root, factory) { if (typeof define === "function" && define.amd) { define([ "jquery" ], function(a0) { return factory(a0); }); } else if (typeof module === "object" && module.exports) { module.exports = factory(require("jquery")); } else { factory(root["jQuery"]); } })(this, function($) { var _ = function() { "use strict"; return { isMsie: function() { return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; }, isBlankString: function(str) { return !str || /^\s*$/.test(str); }, escapeRegExChars: function(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); }, isString: function(obj) { return typeof obj === "string"; }, isNumber: function(obj) { return typeof obj === "number"; }, isArray: $.isArray, isFunction: $.isFunction, isObject: $.isPlainObject, isUndefined: function(obj) { return typeof obj === "undefined"; }, isElement: function(obj) { return !!(obj && obj.nodeType === 1); }, isJQuery: function(obj) { return obj instanceof $; }, toStr: function toStr(s) { return _.isUndefined(s) || s === null ? "" : s + ""; }, bind: $.proxy, each: function(collection, cb) { $.each(collection, reverseArgs); function reverseArgs(index, value) { return cb(value, index); } }, map: $.map, filter: $.grep, every: function(obj, test) { var result = true; if (!obj) { return result; } $.each(obj, function(key, val) { if (!(result = test.call(null, val, key, obj))) { return false; } }); return !!result; }, some: function(obj, test) { var result = false; if (!obj) { return result; } $.each(obj, function(key, val) { if (result = test.call(null, val, key, obj)) { return false; } }); return !!result; }, mixin: $.extend, identity: function(x) { return x; }, clone: function(obj) { return $.extend(true, {}, obj); }, getIdGenerator: function() { var counter = 0; return function() { return counter++; }; }, templatify: function templatify(obj) { return $.isFunction(obj) ? obj : template; function template() { return String(obj); } }, defer: function(fn) { setTimeout(fn, 0); }, debounce: function(func, wait, immediate) { var timeout, result; return function() { var context = this, args = arguments, later, callNow; later = function() { timeout = null; if (!immediate) { result = func.apply(context, args); } }; callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); } return result; }; }, throttle: function(func, wait) { var context, args, timeout, result, previous, later; previous = 0; later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(), remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }, stringify: function(val) { return _.isString(val) ? val : JSON.stringify(val); }, guid: function() { function _p8(s) { var p = (Math.random().toString(16) + "000000000").substr(2, 8); return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p; } return "tt-" + _p8() + _p8(true) + _p8(true) + _p8(); }, noop: function() {} }; }(); var WWW = function() { "use strict"; var defaultClassNames = { wrapper: "twitter-typeahead", input: "tt-input", hint: "tt-hint", menu: "tt-menu", dataset: "tt-dataset", suggestion: "tt-suggestion", selectable: "tt-selectable", empty: "tt-empty", open: "tt-open", cursor: "tt-cursor", highlight: "tt-highlight" }; return build; function build(o) { var www, classes; classes = _.mixin({}, defaultClassNames, o); www = { css: buildCss(), classes: classes, html: buildHtml(classes), selectors: buildSelectors(classes) }; return { css: www.css, html: www.html, classes: www.classes, selectors: www.selectors, mixin: function(o) { _.mixin(o, www); } }; } function buildHtml(c) { return { wrapper: '', menu: '
' }; } function buildSelectors(classes) { var selectors = {}; _.each(classes, function(v, k) { selectors[k] = "." + v; }); return selectors; } function buildCss() { var css = { wrapper: { position: "relative", display: "inline-block" }, hint: { position: "absolute", top: "0", left: "0", borderColor: "transparent", boxShadow: "none", opacity: "1" }, input: { position: "relative", verticalAlign: "top", backgroundColor: "transparent" }, inputWithNoHint: { position: "relative", verticalAlign: "top" }, menu: { position: "absolute", top: "100%", left: "0", zIndex: "100", display: "none" }, ltr: { left: "0", right: "auto" }, rtl: { left: "auto", right: " 0" } }; if (_.isMsie()) { _.mixin(css.input, { backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" }); } return css; } }(); var EventBus = function() { "use strict"; var namespace, deprecationMap; namespace = "typeahead:"; deprecationMap = { render: "rendered", cursorchange: "cursorchanged", select: "selected", autocomplete: "autocompleted" }; function EventBus(o) { if (!o || !o.el) { $.error("EventBus initialized without el"); } this.$el = $(o.el); } _.mixin(EventBus.prototype, { _trigger: function(type, args) { var $e = $.Event(namespace + type); this.$el.trigger.call(this.$el, $e, args || []); return $e; }, before: function(type) { var args, $e; args = [].slice.call(arguments, 1); $e = this._trigger("before" + type, args); return $e.isDefaultPrevented(); }, trigger: function(type) { var deprecatedType; this._trigger(type, [].slice.call(arguments, 1)); if (deprecatedType = deprecationMap[type]) { this._trigger(deprecatedType, [].slice.call(arguments, 1)); } } }); return EventBus; }(); var EventEmitter = function() { "use strict"; var splitter = /\s+/, nextTick = getNextTick(); return { onSync: onSync, onAsync: onAsync, off: off, trigger: trigger }; function on(method, types, cb, context) { var type; if (!cb) { return this; } types = types.split(splitter); cb = context ? bindContext(cb, context) : cb; this._callbacks = this._callbacks || {}; while (type = types.shift()) { this._callbacks[type] = this._callbacks[type] || { sync: [], async: [] }; this._callbacks[type][method].push(cb); } return this; } function onAsync(types, cb, context) { return on.call(this, "async", types, cb, context); } function onSync(types, cb, context) { return on.call(this, "sync", types, cb, context); } function off(types) { var type; if (!this._callbacks) { return this; } types = types.split(splitter); while (type = types.shift()) { delete this._callbacks[type]; } return this; } function trigger(types) { var type, callbacks, args, syncFlush, asyncFlush; if (!this._callbacks) { return this; } types = types.split(splitter); args = [].slice.call(arguments, 1); while ((type = types.shift()) && (callbacks = this._callbacks[type])) { syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); syncFlush() && nextTick(asyncFlush); } return this; } function getFlush(callbacks, context, args) { return flush; function flush() { var cancelled; for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { cancelled = callbacks[i].apply(context, args) === false; } return !cancelled; } } function getNextTick() { var nextTickFn; if (window.setImmediate) { nextTickFn = function nextTickSetImmediate(fn) { setImmediate(function() { fn(); }); }; } else { nextTickFn = function nextTickSetTimeout(fn) { setTimeout(function() { fn(); }, 0); }; } return nextTickFn; } function bindContext(fn, context) { return fn.bind ? fn.bind(context) : function() { fn.apply(context, [].slice.call(arguments, 0)); }; } }(); var highlight = function(doc) { "use strict"; var defaults = { node: null, pattern: null, tagName: "strong", className: null, wordsOnly: false, caseSensitive: false, diacriticInsensitive: false }; var accented = { A: "[AaªÀ-Åà-åĀ-ąǍǎȀ-ȃȦȧᴬᵃḀḁẚẠ-ảₐ℀℁℻⒜Ⓐⓐ㍱-㍴㎀-㎄㎈㎉㎩-㎯㏂㏊㏟㏿Aa]", B: "[BbᴮᵇḂ-ḇℬ⒝Ⓑⓑ㍴㎅-㎇㏃㏈㏔㏝Bb]", C: "[CcÇçĆ-čᶜ℀ℂ℃℅℆ℭⅭⅽ⒞Ⓒⓒ㍶㎈㎉㎝㎠㎤㏄-㏇Cc]", D: "[DdĎďDŽ-džDZ-dzᴰᵈḊ-ḓⅅⅆⅮⅾ⒟Ⓓⓓ㋏㍲㍷-㍹㎗㎭-㎯㏅㏈Dd]", E: "[EeÈ-Ëè-ëĒ-ěȄ-ȇȨȩᴱᵉḘ-ḛẸ-ẽₑ℡ℯℰⅇ⒠Ⓔⓔ㉐㋍㋎Ee]", F: "[FfᶠḞḟ℉ℱ℻⒡Ⓕⓕ㎊-㎌㎙ff-fflFf]", G: "[GgĜ-ģǦǧǴǵᴳᵍḠḡℊ⒢Ⓖⓖ㋌㋍㎇㎍-㎏㎓㎬㏆㏉㏒㏿Gg]", H: "[HhĤĥȞȟʰᴴḢ-ḫẖℋ-ℎ⒣Ⓗⓗ㋌㍱㎐-㎔㏊㏋㏗Hh]", I: "[IiÌ-Ïì-ïĨ-İIJijǏǐȈ-ȋᴵᵢḬḭỈ-ịⁱℐℑℹⅈⅠ-ⅣⅥ-ⅨⅪⅫⅰ-ⅳⅵ-ⅸⅺⅻ⒤Ⓘⓘ㍺㏌㏕fiffiIi]", J: "[JjIJ-ĵLJ-njǰʲᴶⅉ⒥ⒿⓙⱼJj]", K: "[KkĶķǨǩᴷᵏḰ-ḵK⒦Ⓚⓚ㎄㎅㎉㎏㎑㎘㎞㎢㎦㎪㎸㎾㏀㏆㏍-㏏Kk]", L: "[LlĹ-ŀLJ-ljˡᴸḶḷḺ-ḽℒℓ℡Ⅼⅼ⒧Ⓛⓛ㋏㎈㎉㏐-㏓㏕㏖㏿flfflLl]", M: "[MmᴹᵐḾ-ṃ℠™ℳⅯⅿ⒨Ⓜⓜ㍷-㍹㎃㎆㎎㎒㎖㎙-㎨㎫㎳㎷㎹㎽㎿㏁㏂㏎㏐㏔-㏖㏘㏙㏞㏟Mm]", N: "[NnÑñŃ-ʼnNJ-njǸǹᴺṄ-ṋⁿℕ№⒩Ⓝⓝ㎁㎋㎚㎱㎵㎻㏌㏑Nn]", O: "[OoºÒ-Öò-öŌ-őƠơǑǒǪǫȌ-ȏȮȯᴼᵒỌ-ỏₒ℅№ℴ⒪Ⓞⓞ㍵㏇㏒㏖Oo]", P: "[PpᴾᵖṔ-ṗℙ⒫Ⓟⓟ㉐㍱㍶㎀㎊㎩-㎬㎰㎴㎺㏋㏗-㏚Pp]", Q: "[Qqℚ⒬Ⓠⓠ㏃Qq]", R: "[RrŔ-řȐ-ȓʳᴿᵣṘ-ṛṞṟ₨ℛ-ℝ⒭Ⓡⓡ㋍㍴㎭-㎯㏚㏛Rr]", S: "[SsŚ-šſȘșˢṠ-ṣ₨℁℠⒮Ⓢⓢ㎧㎨㎮-㎳㏛㏜stSs]", T: "[TtŢ-ťȚțᵀᵗṪ-ṱẗ℡™⒯Ⓣⓣ㉐㋏㎔㏏ſtstTt]", U: "[UuÙ-Üù-üŨ-ųƯưǓǔȔ-ȗᵁᵘᵤṲ-ṷỤ-ủ℆⒰Ⓤⓤ㍳㍺Uu]", V: "[VvᵛᵥṼ-ṿⅣ-Ⅷⅳ-ⅷ⒱Ⓥⓥⱽ㋎㍵㎴-㎹㏜㏞Vv]", W: "[WwŴŵʷᵂẀ-ẉẘ⒲Ⓦⓦ㎺-㎿㏝Ww]", X: "[XxˣẊ-ẍₓ℻Ⅸ-Ⅻⅸ-ⅻ⒳Ⓧⓧ㏓Xx]", Y: "[YyÝýÿŶ-ŸȲȳʸẎẏẙỲ-ỹ⒴Ⓨⓨ㏉Yy]", Z: "[ZzŹ-žDZ-dzᶻẐ-ẕℤℨ⒵Ⓩⓩ㎐-㎔Zz]" }; return function hightlight(o) { var regex; o = _.mixin({}, defaults, o); if (!o.node || !o.pattern) { return; } o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly, o.diacriticInsensitive); traverse(o.node, hightlightTextNode); function hightlightTextNode(textNode) { var match, patternNode, wrapperNode; if (match = regex.exec(textNode.data)) { wrapperNode = doc.createElement(o.tagName); o.className && (wrapperNode.className = o.className); patternNode = textNode.splitText(match.index); patternNode.splitText(match[0].length); wrapperNode.appendChild(patternNode.cloneNode(true)); textNode.parentNode.replaceChild(wrapperNode, patternNode); } return !!match; } function traverse(el, hightlightTextNode) { var childNode, TEXT_NODE_TYPE = 3; for (var i = 0; i < el.childNodes.length; i++) { childNode = el.childNodes[i]; if (childNode.nodeType === TEXT_NODE_TYPE) { i += hightlightTextNode(childNode) ? 1 : 0; } else { traverse(childNode, hightlightTextNode); } } } }; function accent_replacer(chr) { return accented[chr.toUpperCase()] || chr; } function getRegex(patterns, caseSensitive, wordsOnly, diacriticInsensitive) { var escapedPatterns = [], regexStr; for (var i = 0, len = patterns.length; i < len; i++) { var escapedWord = _.escapeRegExChars(patterns[i]); if (diacriticInsensitive) { escapedWord = escapedWord.replace(/\S/g, accent_replacer); } escapedPatterns.push(escapedWord); } regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); } }(window.document); var Input = function() { "use strict"; var specialKeyCodeMap; specialKeyCodeMap = { 9: "tab", 27: "esc", 37: "left", 39: "right", 13: "enter", 38: "up", 40: "down" }; function Input(o, www) { var id; o = o || {}; if (!o.input) { $.error("input is missing"); } www.mixin(this); this.$hint = $(o.hint); this.$input = $(o.input); this.$menu = $(o.menu); id = this.$input.attr("id") || _.guid(); this.$menu.attr("id", id + "_listbox"); this.$hint.attr({ "aria-hidden": true }); this.$input.attr({ "aria-owns": id + "_listbox", role: "combobox", "aria-autocomplete": "list", "aria-expanded": false }); this.query = this.$input.val(); this.queryWhenFocused = this.hasFocus() ? this.query : null; this.$overflowHelper = buildOverflowHelper(this.$input); this._checkLanguageDirection(); if (this.$hint.length === 0) { this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; } this.onSync("cursorchange", this._updateDescendent); } Input.normalizeQuery = function(str) { return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " "); }; _.mixin(Input.prototype, EventEmitter, { _onBlur: function onBlur() { this.resetInputValue(); this.trigger("blurred"); }, _onFocus: function onFocus() { this.queryWhenFocused = this.query; this.trigger("focused"); }, _onKeydown: function onKeydown($e) { var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; this._managePreventDefault(keyName, $e); if (keyName && this._shouldTrigger(keyName, $e)) { this.trigger(keyName + "Keyed", $e); } }, _onInput: function onInput() { this._setQuery(this.getInputValue()); this.clearHintIfInvalid(); this._checkLanguageDirection(); }, _managePreventDefault: function managePreventDefault(keyName, $e) { var preventDefault; switch (keyName) { case "up": case "down": preventDefault = !withModifier($e); break; default: preventDefault = false; } preventDefault && $e.preventDefault(); }, _shouldTrigger: function shouldTrigger(keyName, $e) { var trigger; switch (keyName) { case "tab": trigger = !withModifier($e); break; default: trigger = true; } return trigger; }, _checkLanguageDirection: function checkLanguageDirection() { var dir = (this.$input.css("direction") || "ltr").toLowerCase(); if (this.dir !== dir) { this.dir = dir; this.$hint.attr("dir", dir); this.trigger("langDirChanged", dir); } }, _setQuery: function setQuery(val, silent) { var areEquivalent, hasDifferentWhitespace; areEquivalent = areQueriesEquivalent(val, this.query); hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false; this.query = val; if (!silent && !areEquivalent) { this.trigger("queryChanged", this.query); } else if (!silent && hasDifferentWhitespace) { this.trigger("whitespaceChanged", this.query); } }, _updateDescendent: function updateDescendent(event, id) { this.$input.attr("aria-activedescendant", id); }, bind: function() { var that = this, onBlur, onFocus, onKeydown, onInput; onBlur = _.bind(this._onBlur, this); onFocus = _.bind(this._onFocus, this); onKeydown = _.bind(this._onKeydown, this); onInput = _.bind(this._onInput, this); this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); if (!_.isMsie() || _.isMsie() > 9) { this.$input.on("input.tt", onInput); } else { this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { if (specialKeyCodeMap[$e.which || $e.keyCode]) { return; } _.defer(_.bind(that._onInput, that, $e)); }); } return this; }, focus: function focus() { this.$input.focus(); }, blur: function blur() { this.$input.blur(); }, getLangDir: function getLangDir() { return this.dir; }, getQuery: function getQuery() { return this.query || ""; }, setQuery: function setQuery(val, silent) { this.setInputValue(val); this._setQuery(val, silent); }, hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() { return this.query !== this.queryWhenFocused; }, getInputValue: function getInputValue() { return this.$input.val(); }, setInputValue: function setInputValue(value) { this.$input.val(value); this.clearHintIfInvalid(); this._checkLanguageDirection(); }, resetInputValue: function resetInputValue() { this.setInputValue(this.query); }, getHint: function getHint() { return this.$hint.val(); }, setHint: function setHint(value) { this.$hint.val(value); }, clearHint: function clearHint() { this.setHint(""); }, clearHintIfInvalid: function clearHintIfInvalid() { var val, hint, valIsPrefixOfHint, isValid; val = this.getInputValue(); hint = this.getHint(); valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); !isValid && this.clearHint(); }, hasFocus: function hasFocus() { return this.$input.is(":focus"); }, hasOverflow: function hasOverflow() { var constraint = this.$input.width() - 2; this.$overflowHelper.text(this.getInputValue()); return this.$overflowHelper.width() >= constraint; }, isCursorAtEnd: function() { var valueLength, selectionStart, range; valueLength = this.$input.val().length; selectionStart = this.$input[0].selectionStart; if (_.isNumber(selectionStart)) { return selectionStart === valueLength; } else if (document.selection) { range = document.selection.createRange(); range.moveStart("character", -valueLength); return valueLength === range.text.length; } return true; }, destroy: function destroy() { this.$hint.off(".tt"); this.$input.off(".tt"); this.$overflowHelper.remove(); this.$hint = this.$input = this.$overflowHelper = $("
"); }, setAriaExpanded: function setAriaExpanded(value) { this.$input.attr("aria-expanded", value); } }); return Input; function buildOverflowHelper($input) { return $('').css({ position: "absolute", visibility: "hidden", whiteSpace: "pre", fontFamily: $input.css("font-family"), fontSize: $input.css("font-size"), fontStyle: $input.css("font-style"), fontVariant: $input.css("font-variant"), fontWeight: $input.css("font-weight"), wordSpacing: $input.css("word-spacing"), letterSpacing: $input.css("letter-spacing"), textIndent: $input.css("text-indent"), textRendering: $input.css("text-rendering"), textTransform: $input.css("text-transform") }).insertAfter($input); } function areQueriesEquivalent(a, b) { return Input.normalizeQuery(a) === Input.normalizeQuery(b); } function withModifier($e) { return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; } }(); var Dataset = function() { "use strict"; var keys, nameGenerator; keys = { dataset: "tt-selectable-dataset", val: "tt-selectable-display", obj: "tt-selectable-object" }; nameGenerator = _.getIdGenerator(); function Dataset(o, www) { o = o || {}; o.templates = o.templates || {}; o.templates.notFound = o.templates.notFound || o.templates.empty; if (!o.source) { $.error("missing source"); } if (!o.node) { $.error("missing node"); } if (o.name && !isValidName(o.name)) { $.error("invalid dataset name: " + o.name); } www.mixin(this); this.highlight = !!o.highlight; this.name = _.toStr(o.name || nameGenerator()); this.limit = o.limit || 5; this.displayFn = getDisplayFn(o.display || o.displayKey); this.templates = getTemplates(o.templates, this.displayFn); this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source; this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async; this._resetLastSuggestion(); this.$el = $(o.node).attr("role", "presentation").addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name); } Dataset.extractData = function extractData(el) { var $el = $(el); if ($el.data(keys.obj)) { return { dataset: $el.data(keys.dataset) || "", val: $el.data(keys.val) || "", obj: $el.data(keys.obj) || null }; } return null; }; _.mixin(Dataset.prototype, EventEmitter, { _overwrite: function overwrite(query, suggestions) { suggestions = suggestions || []; if (suggestions.length) { this._renderSuggestions(query, suggestions); } else if (this.async && this.templates.pending) { this._renderPending(query); } else if (!this.async && this.templates.notFound) { this._renderNotFound(query); } else { this._empty(); } this.trigger("rendered", suggestions, false, this.name); }, _append: function append(query, suggestions) { suggestions = suggestions || []; if (suggestions.length && this.$lastSuggestion.length) { this._appendSuggestions(query, suggestions); } else if (suggestions.length) { this._renderSuggestions(query, suggestions); } else if (!this.$lastSuggestion.length && this.templates.notFound) { this._renderNotFound(query); } this.trigger("rendered", suggestions, true, this.name); }, _renderSuggestions: function renderSuggestions(query, suggestions) { var $fragment; $fragment = this._getSuggestionsFragment(query, suggestions); this.$lastSuggestion = $fragment.children().last(); this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions)); }, _appendSuggestions: function appendSuggestions(query, suggestions) { var $fragment, $lastSuggestion; $fragment = this._getSuggestionsFragment(query, suggestions); $lastSuggestion = $fragment.children().last(); this.$lastSuggestion.after($fragment); this.$lastSuggestion = $lastSuggestion; }, _renderPending: function renderPending(query) { var template = this.templates.pending; this._resetLastSuggestion(); template && this.$el.html(template({ query: query, dataset: this.name })); }, _renderNotFound: function renderNotFound(query) { var template = this.templates.notFound; this._resetLastSuggestion(); template && this.$el.html(template({ query: query, dataset: this.name })); }, _empty: function empty() { this.$el.empty(); this._resetLastSuggestion(); }, _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) { var that = this, fragment; fragment = document.createDocumentFragment(); _.each(suggestions, function getSuggestionNode(suggestion) { var $el, context; context = that._injectQuery(query, suggestion); $el = $(that.templates.suggestion(context)).data(keys.dataset, that.name).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable); fragment.appendChild($el[0]); }); this.highlight && highlight({ className: this.classes.highlight, node: fragment, pattern: query }); return $(fragment); }, _getFooter: function getFooter(query, suggestions) { return this.templates.footer ? this.templates.footer({ query: query, suggestions: suggestions, dataset: this.name }) : null; }, _getHeader: function getHeader(query, suggestions) { return this.templates.header ? this.templates.header({ query: query, suggestions: suggestions, dataset: this.name }) : null; }, _resetLastSuggestion: function resetLastSuggestion() { this.$lastSuggestion = $(); }, _injectQuery: function injectQuery(query, obj) { return _.isObject(obj) ? _.mixin({ _query: query }, obj) : obj; }, update: function update(query) { var that = this, canceled = false, syncCalled = false, rendered = 0; this.cancel(); this.cancel = function cancel() { canceled = true; that.cancel = $.noop; that.async && that.trigger("asyncCanceled", query, that.name); }; this.source(query, sync, async); !syncCalled && sync([]); function sync(suggestions) { if (syncCalled) { return; } syncCalled = true; suggestions = (suggestions || []).slice(0, that.limit); rendered = suggestions.length; that._overwrite(query, suggestions); if (rendered < that.limit && that.async) { that.trigger("asyncRequested", query, that.name); } } function async(suggestions) { suggestions = suggestions || []; if (!canceled && rendered < that.limit) { that.cancel = $.noop; var idx = Math.abs(rendered - that.limit); rendered += idx; that._append(query, suggestions.slice(0, idx)); that.async && that.trigger("asyncReceived", query, that.name); } } }, cancel: $.noop, clear: function clear() { this._empty(); this.cancel(); this.trigger("cleared"); }, isEmpty: function isEmpty() { return this.$el.is(":empty"); }, destroy: function destroy() { this.$el = $("
"); } }); return Dataset; function getDisplayFn(display) { display = display || _.stringify; return _.isFunction(display) ? display : displayFn; function displayFn(obj) { return obj[display]; } } function getTemplates(templates, displayFn) { return { notFound: templates.notFound && _.templatify(templates.notFound), pending: templates.pending && _.templatify(templates.pending), header: templates.header && _.templatify(templates.header), footer: templates.footer && _.templatify(templates.footer), suggestion: templates.suggestion ? userSuggestionTemplate : suggestionTemplate }; function userSuggestionTemplate(context) { var template = templates.suggestion; return $(template(context)).attr("id", _.guid()); } function suggestionTemplate(context) { return $('
').attr("id", _.guid()).text(displayFn(context)); } } function isValidName(str) { return /^[_a-zA-Z0-9-]+$/.test(str); } }(); var Menu = function() { "use strict"; function Menu(o, www) { var that = this; o = o || {}; if (!o.node) { $.error("node is required"); } www.mixin(this); this.$node = $(o.node); this.query = null; this.datasets = _.map(o.datasets, initializeDataset); function initializeDataset(oDataset) { var node = that.$node.find(oDataset.node).first(); oDataset.node = node.length ? node : $("
").appendTo(that.$node); return new Dataset(oDataset, www); } } _.mixin(Menu.prototype, EventEmitter, { _onSelectableClick: function onSelectableClick($e) { this.trigger("selectableClicked", $($e.currentTarget)); }, _onRendered: function onRendered(type, dataset, suggestions, async) { this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); this.trigger("datasetRendered", dataset, suggestions, async); }, _onCleared: function onCleared() { this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty()); this.trigger("datasetCleared"); }, _propagate: function propagate() { this.trigger.apply(this, arguments); }, _allDatasetsEmpty: function allDatasetsEmpty() { return _.every(this.datasets, _.bind(function isDatasetEmpty(dataset) { var isEmpty = dataset.isEmpty(); this.$node.attr("aria-expanded", !isEmpty); return isEmpty; }, this)); }, _getSelectables: function getSelectables() { return this.$node.find(this.selectors.selectable); }, _removeCursor: function _removeCursor() { var $selectable = this.getActiveSelectable(); $selectable && $selectable.removeClass(this.classes.cursor); }, _ensureVisible: function ensureVisible($el) { var elTop, elBottom, nodeScrollTop, nodeHeight; elTop = $el.position().top; elBottom = elTop + $el.outerHeight(true); nodeScrollTop = this.$node.scrollTop(); nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10); if (elTop < 0) { this.$node.scrollTop(nodeScrollTop + elTop); } else if (nodeHeight < elBottom) { this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight)); } }, bind: function() { var that = this, onSelectableClick; onSelectableClick = _.bind(this._onSelectableClick, this); this.$node.on("click.tt", this.selectors.selectable, onSelectableClick); this.$node.on("mouseover", this.selectors.selectable, function() { that.setCursor($(this)); }); this.$node.on("mouseleave", function() { that._removeCursor(); }); _.each(this.datasets, function(dataset) { dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that); }); return this; }, isOpen: function isOpen() { return this.$node.hasClass(this.classes.open); }, open: function open() { this.$node.scrollTop(0); this.$node.addClass(this.classes.open); }, close: function close() { this.$node.attr("aria-expanded", false); this.$node.removeClass(this.classes.open); this._removeCursor(); }, setLanguageDirection: function setLanguageDirection(dir) { this.$node.attr("dir", dir); }, selectableRelativeToCursor: function selectableRelativeToCursor(delta) { var $selectables, $oldCursor, oldIndex, newIndex; $oldCursor = this.getActiveSelectable(); $selectables = this._getSelectables(); oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1; newIndex = oldIndex + delta; newIndex = (newIndex + 1) % ($selectables.length + 1) - 1; newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex; return newIndex === -1 ? null : $selectables.eq(newIndex); }, setCursor: function setCursor($selectable) { this._removeCursor(); if ($selectable = $selectable && $selectable.first()) { $selectable.addClass(this.classes.cursor); this._ensureVisible($selectable); } }, getSelectableData: function getSelectableData($el) { return $el && $el.length ? Dataset.extractData($el) : null; }, getActiveSelectable: function getActiveSelectable() { var $selectable = this._getSelectables().filter(this.selectors.cursor).first(); return $selectable.length ? $selectable : null; }, getTopSelectable: function getTopSelectable() { var $selectable = this._getSelectables().first(); return $selectable.length ? $selectable : null; }, update: function update(query) { var isValidUpdate = query !== this.query; if (isValidUpdate) { this.query = query; _.each(this.datasets, updateDataset); } return isValidUpdate; function updateDataset(dataset) { dataset.update(query); } }, empty: function empty() { _.each(this.datasets, clearDataset); this.query = null; this.$node.addClass(this.classes.empty); function clearDataset(dataset) { dataset.clear(); } }, destroy: function destroy() { this.$node.off(".tt"); this.$node = $("
"); _.each(this.datasets, destroyDataset); function destroyDataset(dataset) { dataset.destroy(); } } }); return Menu; }(); var Status = function() { "use strict"; function Status(options) { this.$el = $("", { role: "status", "aria-live": "polite" }).css({ position: "absolute", padding: "0", border: "0", height: "1px", width: "1px", "margin-bottom": "-1px", "margin-right": "-1px", overflow: "hidden", clip: "rect(0 0 0 0)", "white-space": "nowrap" }); options.$input.after(this.$el); _.each(options.menu.datasets, _.bind(function(dataset) { if (dataset.onSync) { dataset.onSync("rendered", _.bind(this.update, this)); dataset.onSync("cleared", _.bind(this.cleared, this)); } }, this)); } _.mixin(Status.prototype, { update: function update(event, suggestions) { var length = suggestions.length; var words; if (length === 1) { words = { result: "result", is: "is" }; } else { words = { result: "results", is: "are" }; } this.$el.text(length + " " + words.result + " " + words.is + " available, use up and down arrow keys to navigate."); }, cleared: function() { this.$el.text(""); } }); return Status; }(); var DefaultMenu = function() { "use strict"; var s = Menu.prototype; function DefaultMenu() { Menu.apply(this, [].slice.call(arguments, 0)); } _.mixin(DefaultMenu.prototype, Menu.prototype, { open: function open() { !this._allDatasetsEmpty() && this._show(); return s.open.apply(this, [].slice.call(arguments, 0)); }, close: function close() { this._hide(); return s.close.apply(this, [].slice.call(arguments, 0)); }, _onRendered: function onRendered() { if (this._allDatasetsEmpty()) { this._hide(); } else { this.isOpen() && this._show(); } return s._onRendered.apply(this, [].slice.call(arguments, 0)); }, _onCleared: function onCleared() { if (this._allDatasetsEmpty()) { this._hide(); } else { this.isOpen() && this._show(); } return s._onCleared.apply(this, [].slice.call(arguments, 0)); }, setLanguageDirection: function setLanguageDirection(dir) { this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl); return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0)); }, _hide: function hide() { this.$node.hide(); }, _show: function show() { this.$node.css("display", "block"); } }); return DefaultMenu; }(); var Typeahead = function() { "use strict"; function Typeahead(o, www) { var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged; o = o || {}; if (!o.input) { $.error("missing input"); } if (!o.menu) { $.error("missing menu"); } if (!o.eventBus) { $.error("missing event bus"); } www.mixin(this); this.eventBus = o.eventBus; this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; this.input = o.input; this.menu = o.menu; this.enabled = true; this.autoselect = !!o.autoselect; this.active = false; this.input.hasFocus() && this.activate(); this.dir = this.input.getLangDir(); this._hacks(); this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this); onFocused = c(this, "activate", "open", "_onFocused"); onBlurred = c(this, "deactivate", "_onBlurred"); onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed"); onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed"); onEscKeyed = c(this, "isActive", "_onEscKeyed"); onUpKeyed = c(this, "isActive", "open", "_onUpKeyed"); onDownKeyed = c(this, "isActive", "open", "_onDownKeyed"); onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed"); onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed"); onQueryChanged = c(this, "_openIfActive", "_onQueryChanged"); onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged"); this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this); } _.mixin(Typeahead.prototype, { _hacks: function hacks() { var $input, $menu; $input = this.input.$input || $("
"); $menu = this.menu.$node || $("
"); $input.on("blur.tt", function($e) { var active, isActive, hasActive; active = document.activeElement; isActive = $menu.is(active); hasActive = $menu.has(active).length > 0; if (_.isMsie() && (isActive || hasActive)) { $e.preventDefault(); $e.stopImmediatePropagation(); _.defer(function() { $input.focus(); }); } }); $menu.on("mousedown.tt", function($e) { $e.preventDefault(); }); }, _onSelectableClicked: function onSelectableClicked(type, $el) { this.select($el); }, _onDatasetCleared: function onDatasetCleared() { this._updateHint(); }, _onDatasetRendered: function onDatasetRendered(type, suggestions, async, dataset) { this._updateHint(); if (this.autoselect) { var cursorClass = this.selectors.cursor.substr(1); this.menu.$node.find(this.selectors.suggestion).first().addClass(cursorClass); } this.eventBus.trigger("render", suggestions, async, dataset); }, _onAsyncRequested: function onAsyncRequested(type, dataset, query) { this.eventBus.trigger("asyncrequest", query, dataset); }, _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) { this.eventBus.trigger("asynccancel", query, dataset); }, _onAsyncReceived: function onAsyncReceived(type, dataset, query) { this.eventBus.trigger("asyncreceive", query, dataset); }, _onFocused: function onFocused() { this._minLengthMet() && this.menu.update(this.input.getQuery()); }, _onBlurred: function onBlurred() { if (this.input.hasQueryChangedSinceLastFocus()) { this.eventBus.trigger("change", this.input.getQuery()); } }, _onEnterKeyed: function onEnterKeyed(type, $e) { var $selectable; if ($selectable = this.menu.getActiveSelectable()) { if (this.select($selectable)) { $e.preventDefault(); $e.stopPropagation(); } } else if (this.autoselect) { if (this.select(this.menu.getTopSelectable())) { $e.preventDefault(); $e.stopPropagation(); } } }, _onTabKeyed: function onTabKeyed(type, $e) { var $selectable; if ($selectable = this.menu.getActiveSelectable()) { this.select($selectable) && $e.preventDefault(); } else if (this.autoselect) { if ($selectable = this.menu.getTopSelectable()) { this.autocomplete($selectable) && $e.preventDefault(); } } }, _onEscKeyed: function onEscKeyed() { this.close(); }, _onUpKeyed: function onUpKeyed() { this.moveCursor(-1); }, _onDownKeyed: function onDownKeyed() { this.moveCursor(+1); }, _onLeftKeyed: function onLeftKeyed() { if (this.dir === "rtl" && this.input.isCursorAtEnd()) { this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); } }, _onRightKeyed: function onRightKeyed() { if (this.dir === "ltr" && this.input.isCursorAtEnd()) { this.autocomplete(this.menu.getActiveSelectable() || this.menu.getTopSelectable()); } }, _onQueryChanged: function onQueryChanged(e, query) { this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty(); }, _onWhitespaceChanged: function onWhitespaceChanged() { this._updateHint(); }, _onLangDirChanged: function onLangDirChanged(e, dir) { if (this.dir !== dir) { this.dir = dir; this.menu.setLanguageDirection(dir); } }, _openIfActive: function openIfActive() { this.isActive() && this.open(); }, _minLengthMet: function minLengthMet(query) { query = _.isString(query) ? query : this.input.getQuery() || ""; return query.length >= this.minLength; }, _updateHint: function updateHint() { var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match; $selectable = this.menu.getTopSelectable(); data = this.menu.getSelectableData($selectable); val = this.input.getInputValue(); if (data && !_.isBlankString(val) && !this.input.hasOverflow()) { query = Input.normalizeQuery(val); escapedQuery = _.escapeRegExChars(query); frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); match = frontMatchRegEx.exec(data.val); match && this.input.setHint(val + match[1]); } else { this.input.clearHint(); } }, isEnabled: function isEnabled() { return this.enabled; }, enable: function enable() { this.enabled = true; }, disable: function disable() { this.enabled = false; }, isActive: function isActive() { return this.active; }, activate: function activate() { if (this.isActive()) { return true; } else if (!this.isEnabled() || this.eventBus.before("active")) { return false; } else { this.active = true; this.eventBus.trigger("active"); return true; } }, deactivate: function deactivate() { if (!this.isActive()) { return true; } else if (this.eventBus.before("idle")) { return false; } else { this.active = false; this.close(); this.eventBus.trigger("idle"); return true; } }, isOpen: function isOpen() { return this.menu.isOpen(); }, open: function open() { if (!this.isOpen() && !this.eventBus.before("open")) { this.input.setAriaExpanded(true); this.menu.open(); this._updateHint(); this.eventBus.trigger("open"); } return this.isOpen(); }, close: function close() { if (this.isOpen() && !this.eventBus.before("close")) { this.input.setAriaExpanded(false); this.menu.close(); this.input.clearHint(); this.input.resetInputValue(); this.eventBus.trigger("close"); } return !this.isOpen(); }, setVal: function setVal(val) { this.input.setQuery(_.toStr(val)); }, getVal: function getVal() { return this.input.getQuery(); }, select: function select($selectable) { var data = this.menu.getSelectableData($selectable); if (data && !this.eventBus.before("select", data.obj, data.dataset)) { this.input.setQuery(data.val, true); this.eventBus.trigger("select", data.obj, data.dataset); this.close(); return true; } return false; }, autocomplete: function autocomplete($selectable) { var query, data, isValid; query = this.input.getQuery(); data = this.menu.getSelectableData($selectable); isValid = data && query !== data.val; if (isValid && !this.eventBus.before("autocomplete", data.obj, data.dataset)) { this.input.setQuery(data.val); this.eventBus.trigger("autocomplete", data.obj, data.dataset); return true; } return false; }, moveCursor: function moveCursor(delta) { var query, $candidate, data, suggestion, datasetName, cancelMove, id; query = this.input.getQuery(); $candidate = this.menu.selectableRelativeToCursor(delta); data = this.menu.getSelectableData($candidate); suggestion = data ? data.obj : null; datasetName = data ? data.dataset : null; id = $candidate ? $candidate.attr("id") : null; this.input.trigger("cursorchange", id); cancelMove = this._minLengthMet() && this.menu.update(query); if (!cancelMove && !this.eventBus.before("cursorchange", suggestion, datasetName)) { this.menu.setCursor($candidate); if (data) { if (typeof data.val === "string") { this.input.setInputValue(data.val); } } else { this.input.resetInputValue(); this._updateHint(); } this.eventBus.trigger("cursorchange", suggestion, datasetName); return true; } return false; }, destroy: function destroy() { this.input.destroy(); this.menu.destroy(); } }); return Typeahead; function c(ctx) { var methods = [].slice.call(arguments, 1); return function() { var args = [].slice.call(arguments); _.each(methods, function(method) { return ctx[method].apply(ctx, args); }); }; } }(); (function() { "use strict"; var old, keys, methods; old = $.fn.typeahead; keys = { www: "tt-www", attrs: "tt-attrs", typeahead: "tt-typeahead" }; methods = { initialize: function initialize(o, datasets) { var www; datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); o = o || {}; www = WWW(o.classNames); return this.each(attach); function attach() { var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, status, typeahead, MenuConstructor; _.each(datasets, function(d) { d.highlight = !!o.highlight; }); $input = $(this); $wrapper = $(www.html.wrapper); $hint = $elOrNull(o.hint); $menu = $elOrNull(o.menu); defaultHint = o.hint !== false && !$hint; defaultMenu = o.menu !== false && !$menu; defaultHint && ($hint = buildHintFromInput($input, www)); defaultMenu && ($menu = $(www.html.menu).css(www.css.menu)); $hint && $hint.val(""); $input = prepInput($input, www); if (defaultHint || defaultMenu) { $wrapper.css(www.css.wrapper); $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint); $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null); } MenuConstructor = defaultMenu ? DefaultMenu : Menu; eventBus = new EventBus({ el: $input }); input = new Input({ hint: $hint, input: $input, menu: $menu }, www); menu = new MenuConstructor({ node: $menu, datasets: datasets }, www); status = new Status({ $input: $input, menu: menu }); typeahead = new Typeahead({ input: input, menu: menu, eventBus: eventBus, minLength: o.minLength, autoselect: o.autoselect }, www); $input.data(keys.www, www); $input.data(keys.typeahead, typeahead); } }, isEnabled: function isEnabled() { var enabled; ttEach(this.first(), function(t) { enabled = t.isEnabled(); }); return enabled; }, enable: function enable() { ttEach(this, function(t) { t.enable(); }); return this; }, disable: function disable() { ttEach(this, function(t) { t.disable(); }); return this; }, isActive: function isActive() { var active; ttEach(this.first(), function(t) { active = t.isActive(); }); return active; }, activate: function activate() { ttEach(this, function(t) { t.activate(); }); return this; }, deactivate: function deactivate() { ttEach(this, function(t) { t.deactivate(); }); return this; }, isOpen: function isOpen() { var open; ttEach(this.first(), function(t) { open = t.isOpen(); }); return open; }, open: function open() { ttEach(this, function(t) { t.open(); }); return this; }, close: function close() { ttEach(this, function(t) { t.close(); }); return this; }, select: function select(el) { var success = false, $el = $(el); ttEach(this.first(), function(t) { success = t.select($el); }); return success; }, autocomplete: function autocomplete(el) { var success = false, $el = $(el); ttEach(this.first(), function(t) { success = t.autocomplete($el); }); return success; }, moveCursor: function moveCursoe(delta) { var success = false; ttEach(this.first(), function(t) { success = t.moveCursor(delta); }); return success; }, val: function val(newVal) { var query; if (!arguments.length) { ttEach(this.first(), function(t) { query = t.getVal(); }); return query; } else { ttEach(this, function(t) { t.setVal(_.toStr(newVal)); }); return this; } }, destroy: function destroy() { ttEach(this, function(typeahead, $input) { revert($input); typeahead.destroy(); }); return this; } }; $.fn.typeahead = function(method) { if (methods[method]) { return methods[method].apply(this, [].slice.call(arguments, 1)); } else { return methods.initialize.apply(this, arguments); } }; $.fn.typeahead.noConflict = function noConflict() { $.fn.typeahead = old; return this; }; function ttEach($els, fn) { $els.each(function() { var $input = $(this), typeahead; (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input); }); } function buildHintFromInput($input, www) { return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop({ readonly: true, required: false }).removeAttr("id name placeholder").removeClass("required").attr({ spellcheck: "false", tabindex: -1 }); } function prepInput($input, www) { $input.data(keys.attrs, { dir: $input.attr("dir"), autocomplete: $input.attr("autocomplete"), spellcheck: $input.attr("spellcheck"), style: $input.attr("style") }); $input.addClass(www.classes.input).attr({ spellcheck: false }); try { !$input.attr("dir") && $input.attr("dir", "auto"); } catch (e) {} return $input; } function getBackgroundStyles($el) { return { backgroundAttachment: $el.css("background-attachment"), backgroundClip: $el.css("background-clip"), backgroundColor: $el.css("background-color"), backgroundImage: $el.css("background-image"), backgroundOrigin: $el.css("background-origin"), backgroundPosition: $el.css("background-position"), backgroundRepeat: $el.css("background-repeat"), backgroundSize: $el.css("background-size") }; } function revert($input) { var www, $wrapper; www = $input.data(keys.www); $wrapper = $input.parent().filter(www.selectors.wrapper); _.each($input.data(keys.attrs), function(val, key) { _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); }); $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input); if ($wrapper.length) { $input.detach().insertAfter($wrapper); $wrapper.remove(); } } function $elOrNull(obj) { var isValid, $el; isValid = _.isJQuery(obj) || _.isElement(obj); $el = isValid ? $(obj).first() : []; return $el.length ? $el : null; } })(); }); ================================================ FILE: docs/search.json ================================================ {"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV4viewSo6UIViewCSgvp":{"name":"view","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV11isAppearingSbvp":{"name":"isAppearing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV12isPresentingSbvp":{"name":"isPresenting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV20isInTabbarControllerSbvp":{"name":"isInTabbarController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV20isInNavbarControllerSbvp":{"name":"isInNavbarController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV9isMatchedSbvp":{"name":"isMatched","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV21isAncestorViewMatchedSbvp":{"name":"isAncestorViewMatched","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV11matchedViewSo6UIViewCSgvp":{"name":"matchedView","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV19matchedAncestorViewSo6UIViewC_AFtSgvp":{"name":"matchedAncestorView","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV18fromViewControllerSo06UIViewF0Cvp":{"name":"fromViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV16toViewControllerSo06UIViewF0Cvp":{"name":"toViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV21currentViewControllerSo06UIViewF0Cvp":{"name":"currentViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroConditionalContext.html#/s:4Hero0A18ConditionalContextV19otherViewControllerSo06UIViewF0Cvp":{"name":"otherViewController","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroConditionalContext"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV05beginC0SayAA0A8ModifierCGSgvp":{"name":"beginState","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV20conditionalModifiersSaySbAA0A18ConditionalContextVc_SayAA0A8ModifierCGtGSgvp":{"name":"conditionalModifiers","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV8positionSo7CGPointVSgvp":{"name":"position","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV4sizeSo6CGSizeVSgvp":{"name":"size","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV9transformSo13CATransform3DVSgvp":{"name":"transform","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7opacitySfSgvp":{"name":"opacity","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12cornerRadius14CoreFoundation7CGFloatVSgvp":{"name":"cornerRadius","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV15backgroundColorSo10CGColorRefaSgvp":{"name":"backgroundColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV9zPosition14CoreFoundation7CGFloatVSgvp":{"name":"zPosition","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11anchorPointSo7CGPointVSgvp":{"name":"anchorPoint","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12contentsRectSo6CGRectVSgvp":{"name":"contentsRect","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13contentsScale14CoreFoundation7CGFloatVSgvp":{"name":"contentsScale","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11borderWidth14CoreFoundation7CGFloatVSgvp":{"name":"borderWidth","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11borderColorSo10CGColorRefaSgvp":{"name":"borderColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV11shadowColorSo10CGColorRefaSgvp":{"name":"shadowColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13shadowOpacitySfSgvp":{"name":"shadowOpacity","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12shadowOffsetSo6CGSizeVSgvp":{"name":"shadowOffset","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12shadowRadius14CoreFoundation7CGFloatVSgvp":{"name":"shadowRadius","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV10shadowPathSo9CGPathRefaSgvp":{"name":"shadowPath","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13masksToBoundsSbSgvp":{"name":"masksToBounds","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV13displayShadowSbvp":{"name":"displayShadow","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7overlaySo10CGColorRefa5color_14CoreFoundation7CGFloatV7opacitytSgvp":{"name":"overlay","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6spring14CoreFoundation7CGFloatV_AGtSgvp":{"name":"spring","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV5delaySdvp":{"name":"delay","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV8durationSdSgvp":{"name":"duration","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV14timingFunctionSo013CAMediaTimingE0CSgvp":{"name":"timingFunction","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV3arc14CoreFoundation7CGFloatVSgvp":{"name":"arc","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6sourceSSSgvp":{"name":"source","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7cascadeSd_AA16CascadeDirectionOSbtSgvp":{"name":"cascade","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV22ignoreSubviewModifiersSbSgvp":{"name":"ignoreSubviewModifiers","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV15coordinateSpaceAA0a10CoordinateE0OSgvp":{"name":"coordinateSpace","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV23useScaleBasedSizeChangeSbSgvp":{"name":"useScaleBasedSizeChange","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12snapshotTypeAA0a8SnapshotE0OSgvp":{"name":"snapshotType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV7nonFadeSbvp":{"name":"nonFade","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV12forceAnimateSbvp":{"name":"forceAnimate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6customSDySSypGSgvp":{"name":"custom","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6appendyyAA0A8ModifierCF":{"name":"append(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateV6append10contentsOfySayAA0A8ModifierCG_tF":{"name":"append(contentsOf:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:4Hero0A11TargetStateVyypSgSScip":{"name":"subscript(_:)","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html#/s:s25ExpressibleByArrayLiteralP05arrayD0x0cD7ElementQzd_tcfc":{"name":"init(arrayLiteral:)","parent_name":"HeroTargetState"},"Structs/HeroTargetState.html":{"name":"HeroTargetState","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Structs/HeroConditionalContext.html":{"name":"HeroConditionalContext","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroTransitionDelegate.html#/s:4Hero0A18TransitionDelegateP04heroB0_9didUpdateyAA0aB0C_AA0aB5StateOtF":{"name":"heroTransition(_:didUpdate:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionDelegate"},"Protocols/HeroTransitionDelegate.html#/s:4Hero0A18TransitionDelegateP04heroB0_9didUpdateyAA0aB0C_SdtF":{"name":"heroTransition(_:didUpdate:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionDelegate"},"Protocols/HeroStringConvertible.html#/s:4Hero0A17StringConvertibleP4from4nodexSgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroStringConvertible"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroWillStartAnimatingFromViewController:":{"name":"heroWillStartAnimatingFrom(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidEndAnimatingFromViewController:":{"name":"heroDidEndAnimatingFrom(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidCancelAnimatingFromViewController:":{"name":"heroDidCancelAnimatingFrom(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroWillStartTransition":{"name":"heroWillStartTransition()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidEndTransition":{"name":"heroDidEndTransition()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidCancelTransition":{"name":"heroDidCancelTransition()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroWillStartAnimatingToViewController:":{"name":"heroWillStartAnimatingTo(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidEndAnimatingToViewController:":{"name":"heroDidEndAnimatingTo(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroViewControllerDelegate.html#/c:@M@Hero@objc(pl)HeroViewControllerDelegate(im)heroDidCancelAnimatingToViewController:":{"name":"heroDidCancelAnimatingTo(viewController:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewControllerDelegate"},"Protocols/HeroProgressUpdateObserver.html#/s:4Hero0A22ProgressUpdateObserverP07heroDidcB08progressySd_tF":{"name":"heroDidUpdateProgress(progress:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroProgressUpdateObserver"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP4heroAA0A10TransitionCSgvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP10canAnimate4view9appearingSbSo6UIViewC_SbtF":{"name":"canAnimate(view:appearing:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP7animate9fromViews02toE0SdSaySo6UIViewCG_AItF":{"name":"animate(fromViews:toViews:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP5cleanyyF":{"name":"clean()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP6seekTo10timePassedySd_tF":{"name":"seekTo(timePassed:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP6resume10timePassed7reverseS2d_SbtF":{"name":"resume(timePassed:reverse:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP5apply5state2toyAA0A11TargetStateV_So6UIViewCtF":{"name":"apply(state:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroAnimator.html#/s:4Hero0A8AnimatorP12changeTarget5state13isDestination2toyAA0aD5StateV_SbSo6UIViewCtF":{"name":"changeTarget(state:isDestination:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroAnimator"},"Protocols/HeroPreprocessor.html#/s:4Hero0A12PreprocessorP4heroAA0A10TransitionCSgvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPreprocessor"},"Protocols/HeroPreprocessor.html#/s:4Hero0A12PreprocessorP7process9fromViews02toE0ySaySo6UIViewCG_AItF":{"name":"process(fromViews:toViews:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPreprocessor"},"Protocols/HeroCustomSnapshotView.html#/s:4Hero0A18CustomSnapshotViewP04heroC0So6UIViewCSgvp":{"name":"heroSnapshot","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCustomSnapshotView"},"Protocols/HeroCompatible.html#/s:4Hero0A10CompatibleP0B4TypeQa":{"name":"CompatibleType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCompatible"},"Protocols/HeroCompatible.html#/s:4Hero0A10CompatibleP4heroAA0A9ExtensionCy0B4TypeQzGvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCompatible"},"Protocols/HeroCompatible.html":{"name":"HeroCompatible","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroCustomSnapshotView.html":{"name":"HeroCustomSnapshotView","abstract":"\u003cp\u003eAllows a view to create their own custom snapshot when using \u003cstrong\u003eOptimized\u003c/strong\u003e snapshot\u003c/p\u003e"},"Protocols/HeroPreprocessor.html":{"name":"HeroPreprocessor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroAnimator.html":{"name":"HeroAnimator","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroProgressUpdateObserver.html":{"name":"HeroProgressUpdateObserver","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroViewControllerDelegate.html":{"name":"HeroViewControllerDelegate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroStringConvertible.html":{"name":"HeroStringConvertible","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Protocols/HeroTransitionDelegate.html":{"name":"HeroTransitionDelegate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Functions.html#/s:4Hero2eeoiySbAA8ExprNodeC_ADtF":{"name":"==(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Extensions/HeroDebugView.html#/gestureRecognizerShouldBegin(_:)":{"name":"gestureRecognizerShouldBegin(_:)","parent_name":"HeroDebugView"},"Extensions/UINavigationController.html#/Operation":{"name":"Operation","parent_name":"UINavigationController"},"Extensions/String.html#/s:SS4HeroE5match5regexSS_SnySiGtSgSS_tF":{"name":"match(regex:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"String"},"Extensions/UITabBarController.html#/s:So18UITabBarControllerC4HeroE07heroTabB13AnimationTypeAC0d7DefaultgH0Ovp":{"name":"heroTabBarAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UITabBarController"},"Extensions/UITabBarController.html#/c:@CM@Hero@@objc(cs)UITabBarController(py)heroTabBarAnimationTypeString":{"name":"heroTabBarAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UITabBarController"},"Extensions/UINavigationController.html#/s:So22UINavigationControllerC4HeroE27heroNavigationAnimationTypeAC0c7DefaultfG0Ovp":{"name":"heroNavigationAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UINavigationController"},"Extensions/UINavigationController.html#/c:@CM@Hero@@objc(cs)UINavigationController(py)heroNavigationAnimationTypeString":{"name":"heroNavigationAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UINavigationController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE22heroModalAnimationTypeAC0c7DefaultfG0Ovp":{"name":"heroModalAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(py)heroModalAnimationTypeString":{"name":"heroModalAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(py)isHeroEnabled":{"name":"isHeroEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(im)ht_dismiss:":{"name":"ht_dismiss(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE015heroReplaceViewB04withyAB_tF":{"name":"heroReplaceViewController(with:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(im)hero_dismissViewController":{"name":"hero_dismissViewController()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/c:@CM@Hero@@objc(cs)UIViewController(im)hero_unwindToRootViewController":{"name":"hero_unwindToRootViewController()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB0yyABF":{"name":"hero_unwindToViewController(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB012withSelectory10ObjectiveC0I0V_tF":{"name":"hero_unwindToViewController(withSelector:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB09withClassyyXlXp_tF":{"name":"hero_unwindToViewController(withClass:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE017hero_unwindToViewB014withMatchBlockySbABXE_tF":{"name":"hero_unwindToViewController(withMatchBlock:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIViewController.html#/s:So16UIViewControllerC4HeroE016hero_replaceViewB04withyAB_tF":{"name":"hero_replaceViewController(with:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIViewController"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)heroID":{"name":"heroID","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)isHeroEnabled":{"name":"isHeroEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)isHeroEnabledForSubviews":{"name":"isHeroEnabledForSubviews","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/s:So6UIViewC4HeroE13heroModifiersSayAC0B8ModifierCGSgvp":{"name":"heroModifiers","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/UIView.html#/c:@CM@Hero@@objc(cs)UIView(py)heroModifierString":{"name":"heroModifierString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"UIView"},"Extensions/CATransform3D.html#/s:SQ2eeoiySbx_xtFZ":{"name":"==(_:_:)","parent_name":"CATransform3D"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE6linearABvpZ":{"name":"linear","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE6easeInABvpZ":{"name":"easeIn","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE7easeOutABvpZ":{"name":"easeOut","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE9easeInOutABvpZ":{"name":"easeInOut","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE8standardABvpZ":{"name":"standard","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE12decelerationABvpZ":{"name":"deceleration","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE12accelerationABvpZ":{"name":"acceleration","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE5sharpABvpZ":{"name":"sharp","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE11easeOutBackABvpZ":{"name":"easeOutBack","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html#/s:So21CAMediaTimingFunctionC4HeroE4from4nameABSgSS_tFZ":{"name":"from(name:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CAMediaTimingFunction"},"Extensions/CAMediaTimingFunction.html":{"name":"CAMediaTimingFunction"},"Extensions/CATransform3D.html":{"name":"CATransform3D"},"Extensions/UIView.html":{"name":"UIView"},"Extensions/UIViewController.html":{"name":"UIViewController"},"Extensions/UINavigationController.html":{"name":"UINavigationController"},"Extensions/UITabBarController.html":{"name":"UITabBarController"},"Extensions/String.html":{"name":"String"},"Extensions/HeroDebugView.html":{"name":"HeroDebugView"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO8possibleyA2CmF":{"name":"possible","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO8notifiedyA2CmF":{"name":"notified","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO8startingyA2CmF":{"name":"starting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO9animatingyA2CmF":{"name":"animating","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroTransitionState.html#/s:4Hero0A15TransitionStateO10completingyA2CmF":{"name":"completing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransitionState"},"Enums/HeroDefaultAnimationType/Strategy.html#/s:4Hero0A20DefaultAnimationTypeO8StrategyO16forceLeftToRightyA2EmF":{"name":"forceLeftToRight","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Strategy"},"Enums/HeroDefaultAnimationType/Strategy.html#/s:4Hero0A20DefaultAnimationTypeO8StrategyO16forceRightToLeftyA2EmF":{"name":"forceRightToLeft","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Strategy"},"Enums/HeroDefaultAnimationType/Strategy.html#/s:4Hero0A20DefaultAnimationTypeO8StrategyO13userInterfaceyA2EmF":{"name":"userInterface","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Strategy"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO4leftyA2EmF":{"name":"left","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO5rightyA2EmF":{"name":"right","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO2upyA2EmF":{"name":"up","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO4downyA2EmF":{"name":"down","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO4from4nodeAESgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO17leadingToTrailingAA07CascadeE0OvpZ":{"name":"leadingToTrailing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO17trailingToLeadingAA07CascadeE0OvpZ":{"name":"trailingToLeading","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO7leadingAEvpZ":{"name":"leading","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html#/s:4Hero0A20DefaultAnimationTypeO9DirectionO8trailingAEvpZ":{"name":"trailing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Direction"},"Enums/HeroDefaultAnimationType/Direction.html":{"name":"Direction","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType/Strategy.html":{"name":"Strategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4autoyA2CmF":{"name":"auto","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4pushyA2C9DirectionO_tcACmF":{"name":"push(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4pullyA2C9DirectionO_tcACmF":{"name":"pull(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO5coveryA2C9DirectionO_tcACmF":{"name":"cover(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO7uncoveryA2C9DirectionO_tcACmF":{"name":"uncover(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO5slideyA2C9DirectionO_tcACmF":{"name":"slide(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO9zoomSlideyA2C9DirectionO_tcACmF":{"name":"zoomSlide(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO6pageInyA2C9DirectionO_tcACmF":{"name":"pageIn(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO7pageOutyA2C9DirectionO_tcACmF":{"name":"pageOut(direction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4fadeyA2CmF":{"name":"fade","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4zoomyA2CmF":{"name":"zoom","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO7zoomOutyA2CmF":{"name":"zoomOut","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO8selectByyA2C_ACtcACmF":{"name":"selectBy(presenting:dismissing:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO11autoReverse10presentingA2C_tFZ":{"name":"autoReverse(presenting:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4noneyA2CmF":{"name":"none","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO5labelSSSgvp":{"name":"label","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/HeroDefaultAnimationType.html#/s:4Hero0A20DefaultAnimationTypeO4from4nodeACSgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDefaultAnimationType"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11topToBottomyA2CmF":{"name":"topToBottom","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11bottomToTopyA2CmF":{"name":"bottomToTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11leftToRightyA2CmF":{"name":"leftToRight","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO11rightToLeftyA2CmF":{"name":"rightToLeft","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO6radialyACSo7CGPointV_tcACmF":{"name":"radial(center:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO13inverseRadialyACSo7CGPointV_tcACmF":{"name":"inverseRadial(center:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO17leadingToTrailingACvpZ":{"name":"leadingToTrailing","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/CascadeDirection.html#/s:4Hero16CascadeDirectionO17trailingToLeadingACvpZ":{"name":"trailingToLeading","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CascadeDirection"},"Enums/ParseError.html#/s:4Hero10ParseErrorO13unexpectTokenyA2CmF":{"name":"unexpectToken","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO17undefinedOperatoryACSScACmF":{"name":"undefinedOperator(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO15expectCharacteryACSJcACmF":{"name":"expectCharacter(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO16expectExpressionyA2CmF":{"name":"expectExpression","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO18expectArgumentListyA2CmF":{"name":"expectArgumentList","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/ParseError.html#/s:4Hero10ParseErrorO18expectFunctionNameyA2CmF":{"name":"expectFunctionName","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ParseError"},"Enums/Token.html#/s:4Hero5TokenO10identifieryACSS_SnySiGtcACmF":{"name":"identifier(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO6numberyACSf_SnySiGtcACmF":{"name":"number(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO10parensOpenyACSnySiGcACmF":{"name":"parensOpen(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO11parensCloseyACSnySiGcACmF":{"name":"parensClose(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO5commayACSnySiGcACmF":{"name":"comma(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/Token.html#/s:4Hero5TokenO5otheryACSS_SnySiGtcACmF":{"name":"other(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Token"},"Enums/HeroViewOrderingStrategy.html#/s:4Hero0A20ViewOrderingStrategyO4autoyA2CmF":{"name":"auto","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewOrderingStrategy"},"Enums/HeroViewOrderingStrategy.html#/s:4Hero0A20ViewOrderingStrategyO06sourceB5OnTopyA2CmF":{"name":"sourceViewOnTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewOrderingStrategy"},"Enums/HeroViewOrderingStrategy.html#/s:4Hero0A20ViewOrderingStrategyO011destinationB5OnTopyA2CmF":{"name":"destinationViewOnTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroViewOrderingStrategy"},"Enums/HeroCoordinateSpace.html#/s:4Hero0A15CoordinateSpaceO6globalyA2CmF":{"name":"global","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCoordinateSpace"},"Enums/HeroCoordinateSpace.html#/s:4Hero0A15CoordinateSpaceO5localyA2CmF":{"name":"local","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroCoordinateSpace"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO9optimizedyA2CmF":{"name":"optimized","abstract":"\u003cp\u003eWill optimize for different type of views","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO6normalyA2CmF":{"name":"normal","abstract":"\u003cp\u003esnapshotView(afterScreenUpdates:)\u003c/p\u003e","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO11layerRenderyA2CmF":{"name":"layerRender","abstract":"\u003cp\u003elayer.render(in: currentContext)\u003c/p\u003e","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html#/s:4Hero0A12SnapshotTypeO02noB0yA2CmF":{"name":"noSnapshot","abstract":"\u003cp\u003ewill not create snapshot. animate the view directly.","parent_name":"HeroSnapshotType"},"Enums/HeroSnapshotType.html":{"name":"HeroSnapshotType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroCoordinateSpace.html":{"name":"HeroCoordinateSpace","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroViewOrderingStrategy.html":{"name":"HeroViewOrderingStrategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/Token.html":{"name":"Token","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/ParseError.html":{"name":"ParseError","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/CascadeDirection.html":{"name":"CascadeDirection","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroDefaultAnimationType.html":{"name":"HeroDefaultAnimationType","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Enums/HeroTransitionState.html":{"name":"HeroTransitionState","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroDebugPlugin.html#/showOnTop":{"name":"showOnTop","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/animate(fromViews:toViews:)":{"name":"animate(fromViews:toViews:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/resume(timePassed:reverse:)":{"name":"resume(timePassed:reverse:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/clean()":{"name":"clean()","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/onDone()":{"name":"onDone()","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/onProcessSliderChanged(progress:)":{"name":"onProcessSliderChanged(progress:)","parent_name":"HeroDebugPlugin"},"Classes/Hero.html#/s:4HeroAAC6sharedAA0A10TransitionCvpZ":{"name":"shared","abstract":"\u003cp\u003eShared singleton object for controlling the transition\u003c/p\u003e","parent_name":"Hero"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC8delegateAA0aB8Delegate_pSgvp":{"name":"delegate","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC16defaultAnimationAA0a7DefaultD4TypeOvp":{"name":"defaultAnimation","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC14containerColorSo7UIColorCvp":{"name":"containerColor","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC24isUserInteractionEnabledSbvp":{"name":"isUserInteractionEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC20viewOrderingStrategyAA0a4ViewdE0Ovp":{"name":"viewOrderingStrategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC33defaultAnimationDirectionStrategyAA0a7DefaultD4TypeO0F0Ovp":{"name":"defaultAnimationDirectionStrategy","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC5stateAA0aB5StateOvp":{"name":"state","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC15isTransitioningSbvp":{"name":"isTransitioning","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC12isPresentingSbvp":{"name":"isPresenting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC13transitioningSbvp":{"name":"transitioning","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC10presentingSbvp":{"name":"presenting","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC9containerSo6UIViewCSgvp":{"name":"container","abstract":"\u003cp\u003econtainer we created to hold all animating views, will be a subview of the","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC16toViewControllerSo06UIViewE0CSgvp":{"name":"toViewController","abstract":"\u003cp\u003edestination view controller\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC18fromViewControllerSo06UIViewE0CSgvp":{"name":"fromViewController","abstract":"\u003cp\u003esource view controller\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC7contextAA0A7ContextCSgvp":{"name":"context","abstract":"\u003cp\u003econtext object holding transition informations\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC11interactiveSbvp":{"name":"interactive","abstract":"\u003cp\u003ewhether or not we are handling transition interactively\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC13totalDurationSdvp":{"name":"totalDuration","abstract":"\u003cp\u003emax duration needed by the animators\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC8progressSdvp":{"name":"progress","abstract":"\u003cp\u003eprogress of the current transition. 0 if no transition is happening\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@M@Hero@objc(cs)HeroTransition(im)init":{"name":"init()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC24observeForProgressUpdate8observeryAA0aeF8Observer_p_tF":{"name":"observeForProgressUpdate(observer:)","abstract":"\u003cp\u003eReceive callbacks on each animation frame.","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC7animateyyF":{"name":"animate()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC8complete8finishedySb_tF":{"name":"complete(finished:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC10transition4from2to2in10completionySo16UIViewControllerC_AJSo0H0CySbcSgtF":{"name":"transition(from:to:in:completion:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC6updateyy14CoreFoundation7CGFloatVF":{"name":"update(_:)","abstract":"\u003cp\u003eUpdate the progress for the interactive transition.\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC6finish7animateySb_tF":{"name":"finish(animate:)","abstract":"\u003cp\u003eFinish the interactive transition.","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC6cancel7animateySb_tF":{"name":"cancel(animate:)","abstract":"\u003cp\u003eCancel the interactive transition.","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC5apply9modifiers2toySayAA0A8ModifierCG_So6UIViewCtF":{"name":"apply(modifiers:to:)","abstract":"\u003cp\u003eOverride modifiers during an interactive animation.\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC12changeTarget9modifiers13isDestination2toySayAA0A8ModifierCG_SbSo6UIViewCtF":{"name":"changeTarget(modifiers:isDestination:to:)","abstract":"\u003cp\u003eOverride target state during an interactive animation.\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/s:4Hero0A10TransitionC5startyyF":{"name":"start()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:willShowViewController:animated:":{"name":"navigationController(_:willShow:animated:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:didShowViewController:animated:":{"name":"navigationController(_:didShow:animated:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:animationControllerForOperation:fromViewController:toViewController:":{"name":"navigationController(_:animationControllerFor:from:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)navigationController:interactionControllerForAnimationController:":{"name":"navigationController(_:interactionControllerFor:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)tabBarController:shouldSelectViewController:":{"name":"tabBarController(_:shouldSelect:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)tabBarController:interactionControllerForAnimationController:":{"name":"tabBarController(_:interactionControllerFor:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)tabBarController:animationControllerForTransitionFromViewController:toViewController:":{"name":"tabBarController(_:animationControllerForTransitionFrom:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animationControllerForPresentedController:presentingController:sourceController:":{"name":"animationController(forPresented:presenting:source:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animationControllerForDismissedController:":{"name":"animationController(forDismissed:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)interactionControllerForDismissal:":{"name":"interactionControllerForDismissal(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)interactionControllerForPresentation:":{"name":"interactionControllerForPresentation(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animateTransition:":{"name":"animateTransition(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)transitionDuration:":{"name":"transitionDuration(using:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)animationEnded:":{"name":"animationEnded(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(py)wantsInteractiveStart":{"name":"wantsInteractiveStart","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/HeroTransition.html#/c:@CM@Hero@objc(cs)HeroTransition(im)startInteractiveTransition:":{"name":"startInteractiveTransition(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroTransition"},"Classes/Parser.html#/s:4Hero6ParserC6tokensACSayAA5TokenOG_tcfc":{"name":"init(tokens:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Parser"},"Classes/Parser.html#/s:4Hero6ParserC5parseSayAA8ExprNodeCGyKF":{"name":"parse()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Parser"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC9prototypeAA09PrototypeC0Cvp":{"name":"prototype","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC4bodyAA04ExprC0Cvp":{"name":"body","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/FunctionNode.html#/s:4Hero12FunctionNodeC9prototype4bodyAcA09PrototypeC0C_AA04ExprC0Ctcfc":{"name":"init(prototype:body:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"FunctionNode"},"Classes/PrototypeNode.html#/s:4Hero13PrototypeNodeC13argumentNamesSaySSGvp":{"name":"argumentNames","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"PrototypeNode"},"Classes/PrototypeNode.html#/s:4Hero13PrototypeNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"PrototypeNode"},"Classes/PrototypeNode.html#/s:4Hero13PrototypeNodeC4name13argumentNamesACSS_SaySSGtcfc":{"name":"init(name:argumentNames:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"PrototypeNode"},"Classes/CallNode.html#/s:4Hero8CallNodeC9argumentsSayAA04ExprC0CGvp":{"name":"arguments","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CallNode"},"Classes/CallNode.html#/s:4Hero8CallNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CallNode"},"Classes/CallNode.html#/s:4Hero8CallNodeC4name9argumentsACSS_SayAA04ExprC0CGtcfc":{"name":"init(name:arguments:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"CallNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC3lhsAA04ExprD0Cvp":{"name":"lhs","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC3rhsAA04ExprD0Cvp":{"name":"rhs","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/BinaryOpNode.html#/s:4Hero12BinaryOpNodeC4name3lhs3rhsACSS_AA04ExprD0CAHtcfc":{"name":"init(name:lhs:rhs:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"BinaryOpNode"},"Classes/VariableNode.html#/s:4Hero12VariableNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"VariableNode"},"Classes/NumberNode.html#/s:4Hero10NumberNodeC5valueSfvp":{"name":"value","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"NumberNode"},"Classes/NumberNode.html#/s:4Hero10NumberNodeC11descriptionSSvp":{"name":"description","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"NumberNode"},"Classes/NumberNode.html#/s:4Hero10NumberNodeC5valueACSf_tcfc":{"name":"init(value:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"NumberNode"},"Classes/ExprNode.html#/s:4Hero8ExprNodeC5rangeSnySiGvp":{"name":"range","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ExprNode"},"Classes/ExprNode.html#/s:4Hero8ExprNodeC4nameSSvp":{"name":"name","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ExprNode"},"Classes/ExprNode.html#/s:s23CustomStringConvertibleP11descriptionSSvp":{"name":"description","parent_name":"ExprNode"},"Classes/ExprNode.html#/s:4Hero8ExprNodeC4nameACSS_tcfc":{"name":"init(name:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"ExprNode"},"Classes/Lexer.html#/s:4Hero5LexerC5inputACSS_tcfc":{"name":"init(input:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Lexer"},"Classes/Lexer.html#/s:4Hero5LexerC8tokenizeSayAA5TokenOGyF":{"name":"tokenize()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"Lexer"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC4heroAA0A10TransitionCSgvp":{"name":"hero","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7contextAA0A7ContextCSgvp":{"name":"context","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC23requirePerFrameCallbackSbvp":{"name":"requirePerFrameCallback","abstract":"\u003cp\u003eDetermines whether or not to receive \u003ccode\u003eseekTo\u003c/code\u003e callback on every frame.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/c:@M@Hero@objc(cs)HeroPlugin(im)init":{"name":"init()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7process9fromViews02toE0ySaySo6UIViewCG_AItF":{"name":"process(fromViews:toViews:)","abstract":"\u003cp\u003eCalled before any animation.","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC10canAnimate4view9appearingSbSo6UIViewC_SbtF":{"name":"canAnimate(view:appearing:)","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7animate9fromViews02toE0SdSaySo6UIViewCG_AItF":{"name":"animate(fromViews:toViews:)","abstract":"\u003cp\u003ePerform the animation.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC5cleanyyF":{"name":"clean()","abstract":"\u003cp\u003eCalled when all animations are completed.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC6seekTo10timePassedySd_tF":{"name":"seekTo(timePassed:)","abstract":"\u003cp\u003eFor supporting interactive animation only.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC6resume10timePassed7reverseS2d_SbtF":{"name":"resume(timePassed:reverse:)","abstract":"\u003cp\u003eFor supporting interactive animation only.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC5apply5state2toyAA0A11TargetStateV_So6UIViewCtF":{"name":"apply(state:to:)","abstract":"\u003cp\u003eFor supporting interactive animation only.\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC12changeTarget5state13isDestination2toyAA0aD5StateV_SbSo6UIViewCtF":{"name":"changeTarget(state:isDestination:to:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC9isEnabledSbvpZ":{"name":"isEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC6enableyyFZ":{"name":"enable()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroPlugin.html#/s:4Hero0A6PluginC7disableyyFZ":{"name":"disable()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroPlugin"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13applyFunctionACyAA0A11TargetStateVzc_tcfc":{"name":"init(applyFunction:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9beginWithyACSayACGFZ":{"name":"beginWith(_:)","abstract":"\u003cp\u003eApply modifiers directly to the view at the start of the transition.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9beginWith9modifiersACSayACG_tFZ":{"name":"beginWith(modifiers:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9beginWithyA2Cd_tFZ":{"name":"beginWith(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC24useGlobalCoordinateSpaceACvpZ":{"name":"useGlobalCoordinateSpace","abstract":"\u003cp\u003eUse global coordinate space.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC22ignoreSubviewModifiersACvpZ":{"name":"ignoreSubviewModifiers","abstract":"\u003cp\u003eignore all heroModifiers attributes for a view\u0026rsquo;s direct subviews.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC22ignoreSubviewModifiers9recursiveACSb_tFZ":{"name":"ignoreSubviewModifiers(recursive:)","abstract":"\u003cp\u003eignore all heroModifiers attributes for a view\u0026rsquo;s subviews.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC20useOptimizedSnapshotACvpZ":{"name":"useOptimizedSnapshot","abstract":"\u003cp\u003eWill create snapshot optimized for different view type.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC17useNormalSnapshotACvpZ":{"name":"useNormalSnapshot","abstract":"\u003cp\u003eCreate snapshot using snapshotView(afterScreenUpdates:).\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC22useLayerRenderSnapshotACvpZ":{"name":"useLayerRenderSnapshot","abstract":"\u003cp\u003eCreate snapshot using layer.render(in: currentContext).","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13useNoSnapshotACvpZ":{"name":"useNoSnapshot","abstract":"\u003cp\u003eForce Hero to not create any snapshot when animating this view.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12forceAnimateACvpZ":{"name":"forceAnimate","abstract":"\u003cp\u003eForce the view to animate.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC23useScaleBasedSizeChangeACvpZ":{"name":"useScaleBasedSizeChange","abstract":"\u003cp\u003eForce Hero use scale based size animation. This will convert all .size modifier into .scale modifier.","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4from4nodeACSgAA8ExprNodeC_tFZ":{"name":"from(node:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4fadeACvpZ":{"name":"fade","abstract":"\u003cp\u003eFade the view during transition\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12forceNonFadeACvpZ":{"name":"forceNonFade","abstract":"\u003cp\u003eForce don\u0026rsquo;t fade view during transition\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC8positionyACSo7CGPointVFZ":{"name":"position(_:)","abstract":"\u003cp\u003eSet the position for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4sizeyACSo6CGSizeVFZ":{"name":"size(_:)","abstract":"\u003cp\u003eSet the size for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9transformyACSo13CATransform3DVFZ":{"name":"transform(_:)","abstract":"\u003cp\u003eSet the transform for the view to animate from/to. Will override previous perspective, scale, translate, \u0026amp; rotate modifiers\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11perspectiveyAC14CoreFoundation7CGFloatVFZ":{"name":"perspective(_:)","abstract":"\u003cp\u003eSet the perspective on the transform. use in combination with the rotate modifier.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC5scale1x1y1zAC14CoreFoundation7CGFloatV_A2JtFZ":{"name":"scale(x:y:z:)","abstract":"\u003cp\u003eScale 3d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC5scaleyAC14CoreFoundation7CGFloatVFZ":{"name":"scale(_:)","abstract":"\u003cp\u003eScale in x \u0026amp; y axis\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9translate1x1y1zAC14CoreFoundation7CGFloatV_A2JtFZ":{"name":"translate(x:y:z:)","abstract":"\u003cp\u003eTranslate 3d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9translate_1zACSo7CGPointV_14CoreFoundation7CGFloatVtFZ":{"name":"translate(_:z:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6rotate1x1y1zAC14CoreFoundation7CGFloatV_A2JtFZ":{"name":"rotate(x:y:z:)","abstract":"\u003cp\u003eRotate 3d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6rotate_1zACSo7CGPointV_14CoreFoundation7CGFloatVtFZ":{"name":"rotate(_:z:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6rotateyAC14CoreFoundation7CGFloatVFZ":{"name":"rotate(_:)","abstract":"\u003cp\u003eRotate 2d\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC15backgroundColoryACSo7UIColorCFZ":{"name":"backgroundColor(_:)","abstract":"\u003cp\u003eSet the backgroundColor for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11borderColoryACSo7UIColorCFZ":{"name":"borderColor(_:)","abstract":"\u003cp\u003eSet the borderColor for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11shadowColoryACSo7UIColorCFZ":{"name":"shadowColor(_:)","abstract":"\u003cp\u003eSet the shadowColor for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7overlay5color7opacityACSo7UIColorC_14CoreFoundation7CGFloatVtFZ":{"name":"overlay(color:opacity:)","abstract":"\u003cp\u003eCreate an overlay on the animating view.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7opacityyAC14CoreFoundation7CGFloatVFZ":{"name":"opacity(_:)","abstract":"\u003cp\u003eSet the opacity for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12cornerRadiusyAC14CoreFoundation7CGFloatVFZ":{"name":"cornerRadius(_:)","abstract":"\u003cp\u003eSet the cornerRadius for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC9zPositionyAC14CoreFoundation7CGFloatVFZ":{"name":"zPosition(_:)","abstract":"\u003cp\u003eSet the zPosition for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12contentsRectyACSo6CGRectVFZ":{"name":"contentsRect(_:)","abstract":"\u003cp\u003eSet the contentsRect for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13contentsScaleyAC14CoreFoundation7CGFloatVFZ":{"name":"contentsScale(_:)","abstract":"\u003cp\u003eSet the contentsScale for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11borderWidthyAC14CoreFoundation7CGFloatVFZ":{"name":"borderWidth(_:)","abstract":"\u003cp\u003eSet the borderWidth for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13shadowOpacityyAC14CoreFoundation7CGFloatVFZ":{"name":"shadowOpacity(_:)","abstract":"\u003cp\u003eSet the shadowOpacity for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12shadowOffsetyACSo6CGSizeVFZ":{"name":"shadowOffset(_:)","abstract":"\u003cp\u003eSet the shadowOffset for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC12shadowRadiusyAC14CoreFoundation7CGFloatVFZ":{"name":"shadowRadius(_:)","abstract":"\u003cp\u003eSet the shadowRadius for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC10shadowPathyACSo9CGPathRefaFZ":{"name":"shadowPath(_:)","abstract":"\u003cp\u003eSet the shadowPath for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13masksToBoundsyACSbFZ":{"name":"masksToBounds(_:)","abstract":"\u003cp\u003eSet the masksToBounds for the view to animate from/to.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC8durationyACSdFZ":{"name":"duration(_:)","abstract":"\u003cp\u003eSets the duration of the animation for a given view. If not used, Hero will use determine the duration based on the distance and size changes.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC20durationMatchLongestACvpZ":{"name":"durationMatchLongest","abstract":"\u003cp\u003eSets the duration of the animation for a given view to match the longest animation of the transition.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC5delayyACSdFZ":{"name":"delay(_:)","abstract":"\u003cp\u003eSets the delay of the animation for a given view.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC14timingFunctionyACSo013CAMediaTimingD0CFZ":{"name":"timingFunction(_:)","abstract":"\u003cp\u003eSets the timing function of the animation for a given view. If not used, Hero will use determine the timing function based on whether or not the view is entering or exiting the screen.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6spring9stiffness7dampingAC14CoreFoundation7CGFloatV_AItFZ":{"name":"spring(stiffness:damping:)","abstract":"\u003cp\u003e(iOS 9+) Use spring animation with custom stiffness \u0026amp; damping. The duration will be automatically calculated. Will be ignored if arc, timingFunction, or duration is set.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC6source6heroIDACSS_tFZ":{"name":"source(heroID:)","abstract":"\u003cp\u003eTransition from/to the state of the view with matching heroID","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC3arcACvpZ":{"name":"arc","abstract":"\u003cp\u003eWorks in combination with position modifier to apply a natural curve when moving to the destination.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC3arc9intensityAC14CoreFoundation7CGFloatV_tFZ":{"name":"arc(intensity:)","abstract":"\u003cp\u003eWorks in combination with position modifier to apply a natural curve when moving to the destination.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7cascadeACvpZ":{"name":"cascade","abstract":"\u003cp\u003eCascade applys increasing delay modifiers to subviews\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC7cascade5delta9direction17delayMatchedViewsACSd_AA16CascadeDirectionOSbtFZ":{"name":"cascade(delta:direction:delayMatchedViews:)","abstract":"\u003cp\u003eCascade applys increasing delay modifiers to subviews\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4whenyACSbAA0A18ConditionalContextVc_SayACGtFZ":{"name":"when(_:_:)","abstract":"\u003cp\u003eApply modifiers only if the condition return true.\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC4whenyACSbAA0A18ConditionalContextVc_ACdtFZ":{"name":"when(_:_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC11whenMatchedyA2Cd_tFZ":{"name":"whenMatched(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC14whenPresentingyA2Cd_tFZ":{"name":"whenPresenting(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC14whenDismissingyA2Cd_tFZ":{"name":"whenDismissing(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC13whenAppearingyA2Cd_tFZ":{"name":"whenAppearing(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroModifier.html#/s:4Hero0A8ModifierC16whenDisappearingyA2Cd_tFZ":{"name":"whenDisappearing(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroModifier"},"Classes/HeroContext.html#/s:4Hero0A7ContextC9containerSo6UIViewCvp":{"name":"container","abstract":"\u003cp\u003eThe container holding all of the animating views\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC9fromViewsSaySo6UIViewCGvp":{"name":"fromViews","abstract":"\u003cp\u003eA flattened list of all views from source ViewController\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC7toViewsSaySo6UIViewCGvp":{"name":"toViews","abstract":"\u003cp\u003eA flattened list of all views from destination ViewController\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC10sourceView3forSo6UIViewCSgSS_tF":{"name":"sourceView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC15destinationView3forSo6UIViewCSgSS_tF":{"name":"destinationView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC10pairedView3forSo6UIViewCSgAG_tF":{"name":"pairedView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC12snapshotView3forSo6UIViewCAG_tF":{"name":"snapshotView(for:)","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextCyAA0A11TargetStateVSgSo6UIViewCcip":{"name":"subscript(_:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC5cleanyyF":{"name":"clean()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC4hide4viewySo6UIViewC_tF":{"name":"hide(view:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroContext.html#/s:4Hero0A7ContextC6unhide4viewySo6UIViewC_tF":{"name":"unhide(view:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroContext"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionC4basexvp":{"name":"base","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE2idSSSgvp":{"name":"id","abstract":"\u003cp\u003e\u003cstrong\u003eID\u003c/strong\u003e is the identifier for the view. When doing a transition between two view controllers,","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE9isEnabledSbvp":{"name":"isEnabled","abstract":"\u003cp\u003e\u003cstrong\u003eisEnabled\u003c/strong\u003e allows to specify whether a view and its subviews should be consider for animations.","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE20isEnabledForSubviewsSbvp":{"name":"isEnabledForSubviews","abstract":"\u003cp\u003e\u003cstrong\u003eisEnabledForSubviews\u003c/strong\u003e allows to specify whether a view\u0026rsquo;s subviews should be consider for animations.","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE9modifiersSayAA0A8ModifierCGSgvp":{"name":"modifiers","abstract":"\u003cp\u003eUse \u003cstrong\u003emodifiers\u003c/strong\u003e to specify animations alongside the main transition. Checkout \u003ccode\u003eHeroModifier.swift\u003c/code\u003e for available modifiers.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo6UIViewCRbzlE14modifierStringSSSgvp":{"name":"modifierString","abstract":"\u003cp\u003emodifierString** provides another way to set \u003cstrong\u003emodifiers\u003c/strong\u003e. It can be assigned through storyboard.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE18modalAnimationTypeAA0a7DefaultfG0Ovp":{"name":"modalAnimationType","abstract":"\u003cp\u003edefault hero animation type for presenting \u0026amp; dismissing modally\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE24modalAnimationTypeStringSSSgvp":{"name":"modalAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE9isEnabledSbvp":{"name":"isEnabled","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo22UINavigationControllerCRbzlE23navigationAnimationTypeAA0a7DefaultfG0Ovp":{"name":"navigationAnimationType","abstract":"\u003cp\u003edefault hero animation type for push and pop within the navigation controller\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo22UINavigationControllerCRbzlE29navigationAnimationTypeStringSSSgvp":{"name":"navigationAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo18UITabBarControllerCRbzlE03tabD13AnimationTypeAA0a7DefaultgH0Ovp":{"name":"tabBarAnimationType","abstract":"\u003cp\u003edefault hero animation type for switching tabs within the tab bar controller\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo18UITabBarControllerCRbzlE03tabD19AnimationTypeStringSSSgvp":{"name":"tabBarAnimationTypeString","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE011dismissViewD010completionyyycSg_tF":{"name":"dismissViewController(completion:)","abstract":"\u003cp\u003eDismiss the current view controller with animation. Will perform a navigationController.popViewController","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE016unwindToRootViewD0yyF":{"name":"unwindToRootViewController()","abstract":"\u003cp\u003eUnwind to the root view controller using Hero\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD0yyAEF":{"name":"unwindToViewController(_:)","abstract":"\u003cp\u003eUnwind to a specific view controller using Hero\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD012withSelectory10ObjectiveC0I0V_tF":{"name":"unwindToViewController(withSelector:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD09withClassyyXlXp_tF":{"name":"unwindToViewController(withClass:)","abstract":"\u003cp\u003eUnwind to a view controller with given class using Hero\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE012unwindToViewD014withMatchBlockySbAEXE_tF":{"name":"unwindToViewController(withMatchBlock:)","abstract":"\u003cp\u003eUnwind to a view controller that the matchBlock returns true on.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroExtension.html#/s:4Hero0A9ExtensionCAASo16UIViewControllerCRbzlE011replaceViewD04with10completionyAE_yycSgtF":{"name":"replaceViewController(with:completion:)","abstract":"\u003cp\u003eReplace the current view controller with another VC on the navigation/modal/root view of UIWindow stack.\u003c/p\u003e","parent_name":"HeroExtension"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC9showOnTopSbvpZ":{"name":"showOnTop","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC7animate9fromViews02toF0SdSaySo6UIViewCG_AItF":{"name":"animate(fromViews:toViews:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC6resume10timePassed7reverseS2d_SbtF":{"name":"resume(timePassed:reverse:)","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC5cleanyyF":{"name":"clean()","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC6onDoneyyF":{"name":"onDone()","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html#/s:4Hero0A11DebugPluginC22onProcessSliderChanged8progressySf_tF":{"name":"onProcessSliderChanged(progress:)","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e","parent_name":"HeroDebugPlugin"},"Classes/HeroDebugPlugin.html":{"name":"HeroDebugPlugin"},"Classes/HeroExtension.html":{"name":"HeroExtension","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroContext.html":{"name":"HeroContext","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroModifier.html":{"name":"HeroModifier","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroPlugin.html":{"name":"HeroPlugin","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/Lexer.html":{"name":"Lexer","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/ExprNode.html":{"name":"ExprNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/NumberNode.html":{"name":"NumberNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/VariableNode.html":{"name":"VariableNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/BinaryOpNode.html":{"name":"BinaryOpNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/CallNode.html":{"name":"CallNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/PrototypeNode.html":{"name":"PrototypeNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/FunctionNode.html":{"name":"FunctionNode","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/Parser.html":{"name":"Parser","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/HeroTransition.html":{"name":"HeroTransition","abstract":"\u003cp\u003eUndocumented\u003c/p\u003e"},"Classes/Hero.html":{"name":"Hero","abstract":"\u003ch3 id='the-singleton-class-object-for-controlling-interactive-transitions' class='heading'\u003eThe singleton class/object for controlling interactive transitions.\u003c/h3\u003e"},"Classes.html":{"name":"Classes","abstract":"\u003cp\u003eThe following classes are available globally.\u003c/p\u003e"},"Enums.html":{"name":"Enumerations","abstract":"\u003cp\u003eThe following enumerations are available globally.\u003c/p\u003e"},"Extensions.html":{"name":"Extensions","abstract":"\u003cp\u003eThe following extensions are available globally.\u003c/p\u003e"},"Functions.html":{"name":"Functions","abstract":"\u003cp\u003eThe following functions are available globally.\u003c/p\u003e"},"Protocols.html":{"name":"Protocols","abstract":"\u003cp\u003eThe following protocols are available globally.\u003c/p\u003e"},"Structs.html":{"name":"Structures","abstract":"\u003cp\u003eThe following structures are available globally.\u003c/p\u003e"}} ================================================ FILE: docs/undocumented.json ================================================ { "warnings": [ { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Debug Plugin/HeroDebugPlugin.swift", "line": 27, "symbol": "HeroDebugPlugin", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Debug Plugin/HeroDebugPlugin.swift", "line": 28, "symbol": "HeroDebugPlugin.showOnTop", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Debug Plugin/HeroDebugPlugin.swift", "line": 76, "symbol": "HeroDebugPlugin", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Debug Plugin/HeroDebugPlugin.swift", "line": 77, "symbol": "HeroDebugPlugin.onDone()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Debug Plugin/HeroDebugPlugin.swift", "line": 87, "symbol": "HeroDebugPlugin.onProcessSliderChanged(progress:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Debug Plugin/HeroDebugView.swift", "line": 195, "symbol": "HeroDebugView.gestureRecognizerShouldBegin(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 28, "symbol": "CAMediaTimingFunction.linear", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 28, "symbol": "CAMediaTimingFunction.linear", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 29, "symbol": "CAMediaTimingFunction.easeIn", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 29, "symbol": "CAMediaTimingFunction.easeIn", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 30, "symbol": "CAMediaTimingFunction.easeOut", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 30, "symbol": "CAMediaTimingFunction.easeOut", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 31, "symbol": "CAMediaTimingFunction.easeInOut", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 31, "symbol": "CAMediaTimingFunction.easeInOut", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 34, "symbol": "CAMediaTimingFunction.standard", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 34, "symbol": "CAMediaTimingFunction.standard", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 35, "symbol": "CAMediaTimingFunction.deceleration", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 35, "symbol": "CAMediaTimingFunction.deceleration", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 36, "symbol": "CAMediaTimingFunction.acceleration", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 36, "symbol": "CAMediaTimingFunction.acceleration", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 37, "symbol": "CAMediaTimingFunction.sharp", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 37, "symbol": "CAMediaTimingFunction.sharp", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 40, "symbol": "CAMediaTimingFunction.easeOutBack", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 40, "symbol": "CAMediaTimingFunction.easeOutBack", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 42, "symbol": "CAMediaTimingFunction.from(name:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift", "line": 42, "symbol": "CAMediaTimingFunction.from(name:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 122, "symbol": "UIView.heroID", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 122, "symbol": "UIView.heroID", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 129, "symbol": "UIView.isHeroEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 129, "symbol": "UIView.isHeroEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 136, "symbol": "UIView.isHeroEnabledForSubviews", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 136, "symbol": "UIView.isHeroEnabledForSubviews", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 142, "symbol": "UIView.heroModifiers", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 142, "symbol": "UIView.heroModifiers", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 149, "symbol": "UIView.heroModifierString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIView+Hero.swift", "line": 149, "symbol": "UIView.heroModifierString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 65, "symbol": "HeroExtension.modalAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 65, "symbol": "HeroExtension.modalAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 71, "symbol": "HeroExtension.isEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 71, "symbol": "HeroExtension.isEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 128, "symbol": "UIViewController.heroModalAnimationType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 128, "symbol": "UIViewController.heroModalAnimationType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 134, "symbol": "UIViewController.heroModalAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 134, "symbol": "UIViewController.heroModalAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 140, "symbol": "UIViewController.isHeroEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 140, "symbol": "UIViewController.isHeroEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 154, "symbol": "HeroExtension.navigationAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 154, "symbol": "HeroExtension.navigationAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 162, "symbol": "UINavigationController.heroNavigationAnimationType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 162, "symbol": "UINavigationController.heroNavigationAnimationType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 169, "symbol": "UINavigationController.heroNavigationAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 169, "symbol": "UINavigationController.heroNavigationAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 193, "symbol": "HeroExtension.tabBarAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 193, "symbol": "HeroExtension.tabBarAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 201, "symbol": "UITabBarController.heroTabBarAnimationType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 201, "symbol": "UITabBarController.heroTabBarAnimationType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 208, "symbol": "UITabBarController.heroTabBarAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 208, "symbol": "UITabBarController.heroTabBarAnimationTypeString", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 242, "symbol": "HeroExtension.unwindToViewController(withSelector:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 242, "symbol": "HeroExtension.unwindToViewController(withSelector:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 346, "symbol": "UIViewController.ht_dismiss(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 346, "symbol": "UIViewController.ht_dismiss(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 351, "symbol": "UIViewController.heroReplaceViewController(with:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 351, "symbol": "UIViewController.heroReplaceViewController(with:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 357, "symbol": "UIViewController.hero_dismissViewController()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 357, "symbol": "UIViewController.hero_dismissViewController()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 363, "symbol": "UIViewController.hero_unwindToRootViewController()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 363, "symbol": "UIViewController.hero_unwindToRootViewController()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 368, "symbol": "UIViewController.hero_unwindToViewController(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 368, "symbol": "UIViewController.hero_unwindToViewController(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 373, "symbol": "UIViewController.hero_unwindToViewController(withSelector:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 373, "symbol": "UIViewController.hero_unwindToViewController(withSelector:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 378, "symbol": "UIViewController.hero_unwindToViewController(withClass:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 378, "symbol": "UIViewController.hero_unwindToViewController(withClass:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 383, "symbol": "UIViewController.hero_unwindToViewController(withMatchBlock:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 383, "symbol": "UIViewController.hero_unwindToViewController(withMatchBlock:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 388, "symbol": "UIViewController.hero_replaceViewController(with:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Extensions/UIViewController+Hero.swift", "line": 388, "symbol": "UIViewController.hero_replaceViewController(with:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 25, "symbol": "HeroCompatible", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 25, "symbol": "HeroCompatible", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 26, "symbol": "HeroCompatible.CompatibleType", "symbol_kind": "source.lang.swift.decl.associatedtype", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 26, "symbol": "HeroCompatible.CompatibleType", "symbol_kind": "source.lang.swift.decl.associatedtype", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 28, "symbol": "HeroCompatible.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 28, "symbol": "HeroCompatible.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 31, "symbol": "HeroCompatible", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 31, "symbol": "HeroCompatible", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 32, "symbol": "HeroCompatible.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 32, "symbol": "HeroCompatible.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 38, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 38, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 39, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 39, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 40, "symbol": "HeroExtension.base", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 40, "symbol": "HeroExtension.base", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 45, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 45, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 146, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 146, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 185, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 185, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 214, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroCompatible.swift", "line": 214, "symbol": "HeroExtension", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 27, "symbol": "HeroContext", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 27, "symbol": "HeroContext", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 84, "symbol": "HeroContext", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 84, "symbol": "HeroContext", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 315, "symbol": "HeroContext.subscript(_:)", "symbol_kind": "source.lang.swift.decl.function.subscript", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 315, "symbol": "HeroContext.subscript(_:)", "symbol_kind": "source.lang.swift.decl.function.subscript", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 324, "symbol": "HeroContext.clean()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 324, "symbol": "HeroContext.clean()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 334, "symbol": "HeroContext", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 334, "symbol": "HeroContext", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 335, "symbol": "HeroContext.hide(view:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 335, "symbol": "HeroContext.hide(view:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 346, "symbol": "HeroContext.unhide(view:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 346, "symbol": "HeroContext.unhide(view:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 418, "symbol": "HeroCustomSnapshotView.heroSnapshot", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroContext.swift", "line": 418, "symbol": "HeroCustomSnapshotView.heroSnapshot", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier+Advanced.swift", "line": 43, "symbol": "HeroModifier.beginWith(modifiers:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier+Advanced.swift", "line": 43, "symbol": "HeroModifier.beginWith(modifiers:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier+Advanced.swift", "line": 47, "symbol": "HeroModifier.beginWith(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier+Advanced.swift", "line": 47, "symbol": "HeroModifier.beginWith(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier+HeroStringConvertible.swift", "line": 29, "symbol": "HeroModifier.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier+HeroStringConvertible.swift", "line": 29, "symbol": "HeroModifier.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 27, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 27, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 28, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 28, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 28, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 28, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 30, "symbol": "HeroModifier.init(applyFunction:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 30, "symbol": "HeroModifier.init(applyFunction:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 36, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 36, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 75, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 75, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 135, "symbol": "HeroModifier.translate(_:z:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 135, "symbol": "HeroModifier.translate(_:z:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 154, "symbol": "HeroModifier.rotate(_:z:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 154, "symbol": "HeroModifier.rotate(_:z:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 169, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 169, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 216, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 216, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 340, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 340, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 398, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 398, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 469, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 469, "symbol": "HeroModifier", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 482, "symbol": "HeroModifier.when(_:_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 482, "symbol": "HeroModifier.when(_:_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 486, "symbol": "HeroModifier.whenMatched(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 486, "symbol": "HeroModifier.whenMatched(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 490, "symbol": "HeroModifier.whenPresenting(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 490, "symbol": "HeroModifier.whenPresenting(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 494, "symbol": "HeroModifier.whenDismissing(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 494, "symbol": "HeroModifier.whenDismissing(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 498, "symbol": "HeroModifier.whenAppearing(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 498, "symbol": "HeroModifier.whenAppearing(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 502, "symbol": "HeroModifier.whenDisappearing(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroModifier.swift", "line": 502, "symbol": "HeroModifier.whenDisappearing(_:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 27, "symbol": "HeroPlugin", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 27, "symbol": "HeroPlugin", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 29, "symbol": "HeroPlugin.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 29, "symbol": "HeroPlugin.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 31, "symbol": "HeroPlugin.context", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 31, "symbol": "HeroPlugin.context", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 47, "symbol": "HeroPlugin.init()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 47, "symbol": "HeroPlugin.init()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 132, "symbol": "HeroPlugin.changeTarget(state:isDestination:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 132, "symbol": "HeroPlugin.changeTarget(state:isDestination:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 136, "symbol": "HeroPlugin", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 136, "symbol": "HeroPlugin", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 137, "symbol": "HeroPlugin.isEnabled", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 137, "symbol": "HeroPlugin.isEnabled", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 149, "symbol": "HeroPlugin.enable()", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 149, "symbol": "HeroPlugin.enable()", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 152, "symbol": "HeroPlugin.disable()", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroPlugin.swift", "line": 152, "symbol": "HeroPlugin.disable()", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 27, "symbol": "HeroSnapshotType", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 27, "symbol": "HeroSnapshotType", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 46, "symbol": "HeroCoordinateSpace", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 46, "symbol": "HeroCoordinateSpace", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 47, "symbol": "HeroCoordinateSpace.global", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 47, "symbol": "HeroCoordinateSpace.global", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 48, "symbol": "HeroCoordinateSpace.local", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 48, "symbol": "HeroCoordinateSpace.local", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 51, "symbol": "HeroTargetState", "symbol_kind": "source.lang.swift.decl.struct", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 51, "symbol": "HeroTargetState", "symbol_kind": "source.lang.swift.decl.struct", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 52, "symbol": "HeroTargetState.beginState", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 52, "symbol": "HeroTargetState.beginState", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 53, "symbol": "HeroTargetState.conditionalModifiers", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 53, "symbol": "HeroTargetState.conditionalModifiers", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 55, "symbol": "HeroTargetState.position", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 55, "symbol": "HeroTargetState.position", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 56, "symbol": "HeroTargetState.size", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 56, "symbol": "HeroTargetState.size", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 57, "symbol": "HeroTargetState.transform", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 57, "symbol": "HeroTargetState.transform", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 58, "symbol": "HeroTargetState.opacity", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 58, "symbol": "HeroTargetState.opacity", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 59, "symbol": "HeroTargetState.cornerRadius", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 59, "symbol": "HeroTargetState.cornerRadius", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 60, "symbol": "HeroTargetState.backgroundColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 60, "symbol": "HeroTargetState.backgroundColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 61, "symbol": "HeroTargetState.zPosition", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 61, "symbol": "HeroTargetState.zPosition", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 62, "symbol": "HeroTargetState.anchorPoint", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 62, "symbol": "HeroTargetState.anchorPoint", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 64, "symbol": "HeroTargetState.contentsRect", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 64, "symbol": "HeroTargetState.contentsRect", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 65, "symbol": "HeroTargetState.contentsScale", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 65, "symbol": "HeroTargetState.contentsScale", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 67, "symbol": "HeroTargetState.borderWidth", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 67, "symbol": "HeroTargetState.borderWidth", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 68, "symbol": "HeroTargetState.borderColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 68, "symbol": "HeroTargetState.borderColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 70, "symbol": "HeroTargetState.shadowColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 70, "symbol": "HeroTargetState.shadowColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 71, "symbol": "HeroTargetState.shadowOpacity", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 71, "symbol": "HeroTargetState.shadowOpacity", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 72, "symbol": "HeroTargetState.shadowOffset", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 72, "symbol": "HeroTargetState.shadowOffset", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 73, "symbol": "HeroTargetState.shadowRadius", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 73, "symbol": "HeroTargetState.shadowRadius", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 74, "symbol": "HeroTargetState.shadowPath", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 74, "symbol": "HeroTargetState.shadowPath", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 75, "symbol": "HeroTargetState.masksToBounds", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 75, "symbol": "HeroTargetState.masksToBounds", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 76, "symbol": "HeroTargetState.displayShadow", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 76, "symbol": "HeroTargetState.displayShadow", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 78, "symbol": "HeroTargetState.overlay", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 78, "symbol": "HeroTargetState.overlay", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 80, "symbol": "HeroTargetState.spring", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 80, "symbol": "HeroTargetState.spring", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 81, "symbol": "HeroTargetState.delay", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 81, "symbol": "HeroTargetState.delay", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 82, "symbol": "HeroTargetState.duration", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 82, "symbol": "HeroTargetState.duration", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 83, "symbol": "HeroTargetState.timingFunction", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 83, "symbol": "HeroTargetState.timingFunction", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 85, "symbol": "HeroTargetState.arc", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 85, "symbol": "HeroTargetState.arc", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 86, "symbol": "HeroTargetState.source", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 86, "symbol": "HeroTargetState.source", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 87, "symbol": "HeroTargetState.cascade", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 87, "symbol": "HeroTargetState.cascade", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 89, "symbol": "HeroTargetState.ignoreSubviewModifiers", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 89, "symbol": "HeroTargetState.ignoreSubviewModifiers", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 90, "symbol": "HeroTargetState.coordinateSpace", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 90, "symbol": "HeroTargetState.coordinateSpace", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 91, "symbol": "HeroTargetState.useScaleBasedSizeChange", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 91, "symbol": "HeroTargetState.useScaleBasedSizeChange", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 92, "symbol": "HeroTargetState.snapshotType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 92, "symbol": "HeroTargetState.snapshotType", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 94, "symbol": "HeroTargetState.nonFade", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 94, "symbol": "HeroTargetState.nonFade", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 95, "symbol": "HeroTargetState.forceAnimate", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 95, "symbol": "HeroTargetState.forceAnimate", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 96, "symbol": "HeroTargetState.custom", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 96, "symbol": "HeroTargetState.custom", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 102, "symbol": "HeroTargetState.append(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 102, "symbol": "HeroTargetState.append(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 106, "symbol": "HeroTargetState.append(contentsOf:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 106, "symbol": "HeroTargetState.append(contentsOf:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 128, "symbol": "HeroTargetState", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTargetState.swift", "line": 128, "symbol": "HeroTargetState", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 27, "symbol": "HeroPreprocessor", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 27, "symbol": "HeroPreprocessor", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 28, "symbol": "HeroPreprocessor.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 28, "symbol": "HeroPreprocessor.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 29, "symbol": "HeroPreprocessor.process(fromViews:toViews:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 29, "symbol": "HeroPreprocessor.process(fromViews:toViews:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 32, "symbol": "HeroAnimator", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 32, "symbol": "HeroAnimator", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 33, "symbol": "HeroAnimator.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 33, "symbol": "HeroAnimator.hero", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 34, "symbol": "HeroAnimator.canAnimate(view:appearing:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 34, "symbol": "HeroAnimator.canAnimate(view:appearing:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 35, "symbol": "HeroAnimator.animate(fromViews:toViews:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 35, "symbol": "HeroAnimator.animate(fromViews:toViews:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 36, "symbol": "HeroAnimator.clean()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 36, "symbol": "HeroAnimator.clean()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 38, "symbol": "HeroAnimator.seekTo(timePassed:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 38, "symbol": "HeroAnimator.seekTo(timePassed:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 39, "symbol": "HeroAnimator.resume(timePassed:reverse:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 39, "symbol": "HeroAnimator.resume(timePassed:reverse:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 40, "symbol": "HeroAnimator.apply(state:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 40, "symbol": "HeroAnimator.apply(state:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 41, "symbol": "HeroAnimator.changeTarget(state:isDestination:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 41, "symbol": "HeroAnimator.changeTarget(state:isDestination:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 44, "symbol": "HeroProgressUpdateObserver", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 44, "symbol": "HeroProgressUpdateObserver", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 45, "symbol": "HeroProgressUpdateObserver.heroDidUpdateProgress(progress:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 45, "symbol": "HeroProgressUpdateObserver.heroDidUpdateProgress(progress:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 48, "symbol": "HeroViewOrderingStrategy", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 48, "symbol": "HeroViewOrderingStrategy", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 49, "symbol": "HeroViewOrderingStrategy.auto", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 49, "symbol": "HeroViewOrderingStrategy.auto", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 49, "symbol": "HeroViewOrderingStrategy.destinationViewOnTop", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 49, "symbol": "HeroViewOrderingStrategy.destinationViewOnTop", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 49, "symbol": "HeroViewOrderingStrategy.sourceViewOnTop", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroTypes.swift", "line": 49, "symbol": "HeroViewOrderingStrategy.sourceViewOnTop", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 27, "symbol": "HeroViewControllerDelegate", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 27, "symbol": "HeroViewControllerDelegate", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 28, "symbol": "HeroViewControllerDelegate.heroWillStartAnimatingFrom(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 28, "symbol": "HeroViewControllerDelegate.heroWillStartAnimatingFrom(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 29, "symbol": "HeroViewControllerDelegate.heroDidEndAnimatingFrom(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 29, "symbol": "HeroViewControllerDelegate.heroDidEndAnimatingFrom(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 30, "symbol": "HeroViewControllerDelegate.heroDidCancelAnimatingFrom(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 30, "symbol": "HeroViewControllerDelegate.heroDidCancelAnimatingFrom(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 32, "symbol": "HeroViewControllerDelegate.heroWillStartTransition()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 32, "symbol": "HeroViewControllerDelegate.heroWillStartTransition()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 33, "symbol": "HeroViewControllerDelegate.heroDidEndTransition()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 33, "symbol": "HeroViewControllerDelegate.heroDidEndTransition()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 34, "symbol": "HeroViewControllerDelegate.heroDidCancelTransition()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 34, "symbol": "HeroViewControllerDelegate.heroDidCancelTransition()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 36, "symbol": "HeroViewControllerDelegate.heroWillStartAnimatingTo(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 36, "symbol": "HeroViewControllerDelegate.heroWillStartAnimatingTo(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 37, "symbol": "HeroViewControllerDelegate.heroDidEndAnimatingTo(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 37, "symbol": "HeroViewControllerDelegate.heroDidEndAnimatingTo(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 38, "symbol": "HeroViewControllerDelegate.heroDidCancelAnimatingTo(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/HeroViewControllerDelegate.swift", "line": 38, "symbol": "HeroViewControllerDelegate.heroDidCancelAnimatingTo(viewController:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/HeroStringConvertible.swift", "line": 25, "symbol": "HeroStringConvertible", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/HeroStringConvertible.swift", "line": 25, "symbol": "HeroStringConvertible", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/HeroStringConvertible.swift", "line": 26, "symbol": "HeroStringConvertible.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/HeroStringConvertible.swift", "line": 26, "symbol": "HeroStringConvertible.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 11, "symbol": "Token", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 11, "symbol": "Token", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 12, "symbol": "Token.identifier(_:_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 12, "symbol": "Token.identifier(_:_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 13, "symbol": "Token.number(_:_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 13, "symbol": "Token.number(_:_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 14, "symbol": "Token.parensOpen(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 14, "symbol": "Token.parensOpen(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 15, "symbol": "Token.parensClose(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 15, "symbol": "Token.parensClose(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 16, "symbol": "Token.comma(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 16, "symbol": "Token.comma(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 17, "symbol": "Token.other(_:_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 17, "symbol": "Token.other(_:_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 30, "symbol": "Lexer", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 30, "symbol": "Lexer", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 32, "symbol": "Lexer.init(input:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 32, "symbol": "Lexer.init(input:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 35, "symbol": "Lexer.tokenize()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Lexer.swift", "line": 35, "symbol": "Lexer.tokenize()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 11, "symbol": "ExprNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 11, "symbol": "ExprNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 12, "symbol": "ExprNode.range", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 12, "symbol": "ExprNode.range", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 13, "symbol": "ExprNode.name", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 13, "symbol": "ExprNode.name", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 17, "symbol": "ExprNode.init(name:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 17, "symbol": "ExprNode.init(name:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 22, "symbol": "==(_:_:)", "symbol_kind": "source.lang.swift.decl.function.free", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 22, "symbol": "==(_:_:)", "symbol_kind": "source.lang.swift.decl.function.free", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 26, "symbol": "NumberNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 26, "symbol": "NumberNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 27, "symbol": "NumberNode.value", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 27, "symbol": "NumberNode.value", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 28, "symbol": "NumberNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 28, "symbol": "NumberNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 31, "symbol": "NumberNode.init(value:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 31, "symbol": "NumberNode.init(value:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 37, "symbol": "VariableNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 37, "symbol": "VariableNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 38, "symbol": "VariableNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 38, "symbol": "VariableNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 43, "symbol": "BinaryOpNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 43, "symbol": "BinaryOpNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 44, "symbol": "BinaryOpNode.lhs", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 44, "symbol": "BinaryOpNode.lhs", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 45, "symbol": "BinaryOpNode.rhs", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 45, "symbol": "BinaryOpNode.rhs", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 46, "symbol": "BinaryOpNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 46, "symbol": "BinaryOpNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 49, "symbol": "BinaryOpNode.init(name:lhs:rhs:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 49, "symbol": "BinaryOpNode.init(name:lhs:rhs:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 56, "symbol": "CallNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 56, "symbol": "CallNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 57, "symbol": "CallNode.arguments", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 57, "symbol": "CallNode.arguments", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 58, "symbol": "CallNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 58, "symbol": "CallNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 61, "symbol": "CallNode.init(name:arguments:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 61, "symbol": "CallNode.init(name:arguments:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 67, "symbol": "PrototypeNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 67, "symbol": "PrototypeNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 68, "symbol": "PrototypeNode.argumentNames", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 68, "symbol": "PrototypeNode.argumentNames", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 69, "symbol": "PrototypeNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 69, "symbol": "PrototypeNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 72, "symbol": "PrototypeNode.init(name:argumentNames:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 72, "symbol": "PrototypeNode.init(name:argumentNames:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 78, "symbol": "FunctionNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 78, "symbol": "FunctionNode", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 79, "symbol": "FunctionNode.prototype", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 79, "symbol": "FunctionNode.prototype", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 80, "symbol": "FunctionNode.body", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 80, "symbol": "FunctionNode.body", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 81, "symbol": "FunctionNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 81, "symbol": "FunctionNode.description", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 84, "symbol": "FunctionNode.init(prototype:body:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Nodes.swift", "line": 84, "symbol": "FunctionNode.init(prototype:body:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 11, "symbol": "ParseError", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 11, "symbol": "ParseError", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 12, "symbol": "ParseError.unexpectToken", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 12, "symbol": "ParseError.unexpectToken", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 13, "symbol": "ParseError.undefinedOperator(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 13, "symbol": "ParseError.undefinedOperator(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 15, "symbol": "ParseError.expectCharacter(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 15, "symbol": "ParseError.expectCharacter(_:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 16, "symbol": "ParseError.expectExpression", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 16, "symbol": "ParseError.expectExpression", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 17, "symbol": "ParseError.expectArgumentList", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 17, "symbol": "ParseError.expectArgumentList", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 18, "symbol": "ParseError.expectFunctionName", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 18, "symbol": "ParseError.expectFunctionName", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 21, "symbol": "Parser", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 21, "symbol": "Parser", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 25, "symbol": "Parser.init(tokens:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 25, "symbol": "Parser.init(tokens:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 156, "symbol": "Parser.parse()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Parser.swift", "line": 156, "symbol": "Parser.parse()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Regex.swift", "line": 13, "symbol": "String.match(regex:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Parser/Regex.swift", "line": 13, "symbol": "String.match(regex:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 29, "symbol": "CascadeDirection", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 29, "symbol": "CascadeDirection", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 30, "symbol": "CascadeDirection.topToBottom", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 30, "symbol": "CascadeDirection.topToBottom", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 31, "symbol": "CascadeDirection.bottomToTop", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 31, "symbol": "CascadeDirection.bottomToTop", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 32, "symbol": "CascadeDirection.leftToRight", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 32, "symbol": "CascadeDirection.leftToRight", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 33, "symbol": "CascadeDirection.rightToLeft", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 33, "symbol": "CascadeDirection.rightToLeft", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 34, "symbol": "CascadeDirection.radial(center:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 34, "symbol": "CascadeDirection.radial(center:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 35, "symbol": "CascadeDirection.inverseRadial(center:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 35, "symbol": "CascadeDirection.inverseRadial(center:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 76, "symbol": "CascadeDirection.leadingToTrailing", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 76, "symbol": "CascadeDirection.leadingToTrailing", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 80, "symbol": "CascadeDirection.trailingToLeading", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/CascadePreprocessor.swift", "line": 80, "symbol": "CascadeDirection.trailingToLeading", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 27, "symbol": "HeroConditionalContext", "symbol_kind": "source.lang.swift.decl.struct", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 27, "symbol": "HeroConditionalContext", "symbol_kind": "source.lang.swift.decl.struct", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 29, "symbol": "HeroConditionalContext.view", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 29, "symbol": "HeroConditionalContext.view", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 31, "symbol": "HeroConditionalContext.isAppearing", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 31, "symbol": "HeroConditionalContext.isAppearing", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 33, "symbol": "HeroConditionalContext.isPresenting", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 33, "symbol": "HeroConditionalContext.isPresenting", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 36, "symbol": "HeroConditionalContext.isInTabbarController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 36, "symbol": "HeroConditionalContext.isInTabbarController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 39, "symbol": "HeroConditionalContext.isInNavbarController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 39, "symbol": "HeroConditionalContext.isInNavbarController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 42, "symbol": "HeroConditionalContext.isMatched", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 42, "symbol": "HeroConditionalContext.isMatched", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 45, "symbol": "HeroConditionalContext.isAncestorViewMatched", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 45, "symbol": "HeroConditionalContext.isAncestorViewMatched", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 49, "symbol": "HeroConditionalContext.matchedView", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 49, "symbol": "HeroConditionalContext.matchedView", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 52, "symbol": "HeroConditionalContext.matchedAncestorView", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 52, "symbol": "HeroConditionalContext.matchedAncestorView", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 63, "symbol": "HeroConditionalContext.fromViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 63, "symbol": "HeroConditionalContext.fromViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 66, "symbol": "HeroConditionalContext.toViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 66, "symbol": "HeroConditionalContext.toViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 69, "symbol": "HeroConditionalContext.currentViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 69, "symbol": "HeroConditionalContext.currentViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 72, "symbol": "HeroConditionalContext.otherViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift", "line": 72, "symbol": "HeroConditionalContext.otherViewController", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 27, "symbol": "HeroDefaultAnimationType", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 27, "symbol": "HeroDefaultAnimationType", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 28, "symbol": "HeroDefaultAnimationType.Direction", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 28, "symbol": "HeroDefaultAnimationType.Direction", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.down", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.down", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.left", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.left", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.right", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.right", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.up", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 29, "symbol": "HeroDefaultAnimationType.Direction.up", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 30, "symbol": "HeroDefaultAnimationType.Direction.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 30, "symbol": "HeroDefaultAnimationType.Direction.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 42, "symbol": "HeroDefaultAnimationType.Direction.leadingToTrailing", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 42, "symbol": "HeroDefaultAnimationType.Direction.leadingToTrailing", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 46, "symbol": "HeroDefaultAnimationType.Direction.trailingToLeading", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 46, "symbol": "HeroDefaultAnimationType.Direction.trailingToLeading", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 50, "symbol": "HeroDefaultAnimationType.Direction.leading", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 50, "symbol": "HeroDefaultAnimationType.Direction.leading", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 54, "symbol": "HeroDefaultAnimationType.Direction.trailing", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 54, "symbol": "HeroDefaultAnimationType.Direction.trailing", "symbol_kind": "source.lang.swift.decl.var.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 59, "symbol": "HeroDefaultAnimationType.Strategy", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 59, "symbol": "HeroDefaultAnimationType.Strategy", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 60, "symbol": "HeroDefaultAnimationType.Strategy.forceLeftToRight", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 60, "symbol": "HeroDefaultAnimationType.Strategy.forceLeftToRight", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 60, "symbol": "HeroDefaultAnimationType.Strategy.forceRightToLeft", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 60, "symbol": "HeroDefaultAnimationType.Strategy.forceRightToLeft", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 60, "symbol": "HeroDefaultAnimationType.Strategy.userInterface", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 60, "symbol": "HeroDefaultAnimationType.Strategy.userInterface", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 73, "symbol": "HeroDefaultAnimationType.auto", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 73, "symbol": "HeroDefaultAnimationType.auto", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 74, "symbol": "HeroDefaultAnimationType.push(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 74, "symbol": "HeroDefaultAnimationType.push(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 75, "symbol": "HeroDefaultAnimationType.pull(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 75, "symbol": "HeroDefaultAnimationType.pull(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 76, "symbol": "HeroDefaultAnimationType.cover(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 76, "symbol": "HeroDefaultAnimationType.cover(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 77, "symbol": "HeroDefaultAnimationType.uncover(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 77, "symbol": "HeroDefaultAnimationType.uncover(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 78, "symbol": "HeroDefaultAnimationType.slide(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 78, "symbol": "HeroDefaultAnimationType.slide(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 79, "symbol": "HeroDefaultAnimationType.zoomSlide(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 79, "symbol": "HeroDefaultAnimationType.zoomSlide(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 80, "symbol": "HeroDefaultAnimationType.pageIn(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 80, "symbol": "HeroDefaultAnimationType.pageIn(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 81, "symbol": "HeroDefaultAnimationType.pageOut(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 81, "symbol": "HeroDefaultAnimationType.pageOut(direction:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 82, "symbol": "HeroDefaultAnimationType.fade", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 82, "symbol": "HeroDefaultAnimationType.fade", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 83, "symbol": "HeroDefaultAnimationType.zoom", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 83, "symbol": "HeroDefaultAnimationType.zoom", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 84, "symbol": "HeroDefaultAnimationType.zoomOut", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 84, "symbol": "HeroDefaultAnimationType.zoomOut", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 86, "symbol": "HeroDefaultAnimationType.selectBy(presenting:dismissing:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 86, "symbol": "HeroDefaultAnimationType.selectBy(presenting:dismissing:)", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 88, "symbol": "HeroDefaultAnimationType.autoReverse(presenting:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 88, "symbol": "HeroDefaultAnimationType.autoReverse(presenting:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 92, "symbol": "HeroDefaultAnimationType.none", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 92, "symbol": "HeroDefaultAnimationType.none", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 170, "symbol": "HeroDefaultAnimationType.label", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 170, "symbol": "HeroDefaultAnimationType.label", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 184, "symbol": "HeroDefaultAnimationType", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 184, "symbol": "HeroDefaultAnimationType", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 185, "symbol": "HeroDefaultAnimationType.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Preprocessors/DefaultAnimationPreprocessor.swift", "line": 185, "symbol": "HeroDefaultAnimationType.from(node:)", "symbol_kind": "source.lang.swift.decl.function.method.static", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+Animate.swift", "line": 27, "symbol": "HeroTransition.animate()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+Animate.swift", "line": 27, "symbol": "HeroTransition.animate()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+Complete.swift", "line": 28, "symbol": "HeroTransition.complete(finished:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+Complete.swift", "line": 28, "symbol": "HeroTransition.complete(finished:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+CustomTransition.swift", "line": 29, "symbol": "HeroTransition.transition(from:to:in:completion:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+CustomTransition.swift", "line": 29, "symbol": "HeroTransition.transition(from:to:in:completion:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+Start.swift", "line": 28, "symbol": "HeroTransition.start()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+Start.swift", "line": 28, "symbol": "HeroTransition.start()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 28, "symbol": "HeroTransition.navigationController(_:willShow:animated:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 28, "symbol": "HeroTransition.navigationController(_:willShow:animated:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 34, "symbol": "HeroTransition.navigationController(_:didShow:animated:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 34, "symbol": "HeroTransition.navigationController(_:didShow:animated:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 40, "symbol": "HeroTransition.navigationController(_:animationControllerFor:from:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 40, "symbol": "HeroTransition.navigationController(_:animationControllerFor:from:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 50, "symbol": "HeroTransition.navigationController(_:interactionControllerFor:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift", "line": 50, "symbol": "HeroTransition.navigationController(_:interactionControllerFor:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift", "line": 28, "symbol": "HeroTransition.tabBarController(_:shouldSelect:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift", "line": 28, "symbol": "HeroTransition.tabBarController(_:shouldSelect:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift", "line": 38, "symbol": "HeroTransition.tabBarController(_:interactionControllerFor:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift", "line": 38, "symbol": "HeroTransition.tabBarController(_:interactionControllerFor:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift", "line": 42, "symbol": "HeroTransition.tabBarController(_:animationControllerForTransitionFrom:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift", "line": 42, "symbol": "HeroTransition.tabBarController(_:animationControllerForTransitionFrom:to:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 32, "symbol": "HeroTransition.animationController(forPresented:presenting:source:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 32, "symbol": "HeroTransition.animationController(forPresented:presenting:source:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 41, "symbol": "HeroTransition.animationController(forDismissed:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 41, "symbol": "HeroTransition.animationController(forDismissed:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 49, "symbol": "HeroTransition.interactionControllerForDismissal(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 49, "symbol": "HeroTransition.interactionControllerForDismissal(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 53, "symbol": "HeroTransition.interactionControllerForPresentation(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 53, "symbol": "HeroTransition.interactionControllerForPresentation(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 59, "symbol": "HeroTransition.animateTransition(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 59, "symbol": "HeroTransition.animateTransition(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 66, "symbol": "HeroTransition.transitionDuration(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 66, "symbol": "HeroTransition.transitionDuration(using:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 70, "symbol": "HeroTransition.animationEnded(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 70, "symbol": "HeroTransition.animationEnded(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 76, "symbol": "HeroTransition.wantsInteractiveStart", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 76, "symbol": "HeroTransition.wantsInteractiveStart", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 79, "symbol": "HeroTransition.startInteractiveTransition(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift", "line": 79, "symbol": "HeroTransition.startInteractiveTransition(_:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 26, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 26, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 27, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 28, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 28, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 48, "symbol": "HeroTransitionDelegate", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 48, "symbol": "HeroTransitionDelegate", "symbol_kind": "source.lang.swift.decl.protocol", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 49, "symbol": "HeroTransitionDelegate.heroTransition(_:didUpdate:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 49, "symbol": "HeroTransitionDelegate.heroTransition(_:didUpdate:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 50, "symbol": "HeroTransitionDelegate.heroTransition(_:didUpdate:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 50, "symbol": "HeroTransitionDelegate.heroTransition(_:didUpdate:)", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 53, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 53, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.class", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 54, "symbol": "HeroTransition.delegate", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 54, "symbol": "HeroTransition.delegate", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 56, "symbol": "HeroTransition.defaultAnimation", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 56, "symbol": "HeroTransition.defaultAnimation", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 57, "symbol": "HeroTransition.containerColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 57, "symbol": "HeroTransition.containerColor", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 58, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 58, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 58, "symbol": "HeroTransition.isUserInteractionEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 58, "symbol": "HeroTransition.isUserInteractionEnabled", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 59, "symbol": "HeroTransition.viewOrderingStrategy", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 59, "symbol": "HeroTransition.viewOrderingStrategy", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 60, "symbol": "HeroTransition.defaultAnimationDirectionStrategy", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 60, "symbol": "HeroTransition.defaultAnimationDirectionStrategy", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 62, "symbol": "HeroTransition.state", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 62, "symbol": "HeroTransition.state", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 72, "symbol": "HeroTransition.isTransitioning", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 72, "symbol": "HeroTransition.isTransitioning", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 73, "symbol": "HeroTransition.isPresenting", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 73, "symbol": "HeroTransition.isPresenting", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 75, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 75, "symbol": "HeroTransition", "symbol_kind": "source.lang.swift.decl.extension", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 76, "symbol": "HeroTransition.transitioning", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 76, "symbol": "HeroTransition.transitioning", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 80, "symbol": "HeroTransition.presenting", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 80, "symbol": "HeroTransition.presenting", "symbol_kind": "source.lang.swift.decl.var.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 183, "symbol": "HeroTransition.init()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransition.swift", "line": 183, "symbol": "HeroTransition.init()", "symbol_kind": "source.lang.swift.decl.function.method.instance", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 25, "symbol": "HeroTransitionState", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 25, "symbol": "HeroTransitionState", "symbol_kind": "source.lang.swift.decl.enum", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 27, "symbol": "HeroTransitionState.possible", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 27, "symbol": "HeroTransitionState.possible", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 31, "symbol": "HeroTransitionState.notified", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 31, "symbol": "HeroTransitionState.notified", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 34, "symbol": "HeroTransitionState.starting", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 34, "symbol": "HeroTransitionState.starting", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 37, "symbol": "HeroTransitionState.animating", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 37, "symbol": "HeroTransitionState.animating", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 40, "symbol": "HeroTransitionState.completing", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" }, { "file": "/Users/jmattiello/Workspace/github/Hero/Sources/Transition/HeroTransitionState.swift", "line": 40, "symbol": "HeroTransitionState.completing", "symbol_kind": "source.lang.swift.decl.enumelement", "warning": "undocumented" } ], "source_directory": "/Users/jmattiello/Workspace/github/Hero" }