├── ActivityIndicatorView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── ActivityIndicatorView.xcscheme ├── Assets ├── demo.gif └── flow-logo@2x.png ├── LICENSE ├── README.md ├── Resources ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-1024.png │ │ ├── Icon-120.png │ │ ├── Icon-121.png │ │ ├── Icon-152.png │ │ ├── Icon-167.png │ │ ├── Icon-180.png │ │ ├── Icon-20.png │ │ ├── Icon-29.png │ │ ├── Icon-40.png │ │ ├── Icon-41.png │ │ ├── Icon-42.png │ │ ├── Icon-58.png │ │ ├── Icon-59.png │ │ ├── Icon-60.png │ │ ├── Icon-76.png │ │ ├── Icon-80.png │ │ ├── Icon-81.png │ │ └── Icon-87.png │ ├── Contents.json │ └── FlowWordmark.imageset │ │ ├── Contents.json │ │ └── FlowWordmark.pdf ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard └── Info.plist └── Sources ├── ActivityIndicatorView.swift ├── ActivityIndicators.swift ├── Animations ├── Barista │ ├── BaristaActivityIndicatorView.swift │ ├── BaristaTimeline.swift │ └── BaristaView.swift ├── Breathe │ ├── BreatheActivityIndicatorView.swift │ ├── BreatheTimeline.swift │ └── BreatheView.swift ├── Caught │ ├── CaughtActivityIndicatorView.swift │ ├── CaughtTimeline.swift │ └── CaughtView.swift ├── Charting │ ├── ChartingActivityIndicatorView.swift │ ├── ChartingTimeline.swift │ └── ChartingView.swift ├── Compass │ ├── CompassActivityIndicatorView.swift │ ├── CompassTimeline.swift │ └── CompassView.swift ├── Cradle │ ├── CradleActivityIndicatorView.swift │ ├── CradleTimeline.swift │ └── CradleView.swift ├── Dashed │ ├── DashedActivityIndicatorView.swift │ ├── DashedTimeline.swift │ └── DashedView.swift ├── Deceptive │ ├── DeceptiveActivityIndicatorView.swift │ ├── DeceptiveTimeline.swift │ └── DeceptiveView.swift ├── Dialed │ ├── DialedActivityIndicatorView.swift │ ├── DialedTimeline.swift │ └── DialedView.swift ├── Differences │ ├── DifferencesActivityIndicatorView.swift │ ├── DifferencesTimeline.swift │ └── DifferencesView.swift ├── DottingAroundCircle │ ├── DottingAroundCircleActivityIndicatorView.swift │ ├── DottingAroundCircleTimeline.swift │ └── DottingAroundCircleView.swift ├── DottingAroundSquare │ ├── DottingAroundSquareActivityIndicatorView.swift │ ├── DottingAroundSquareTimeline.swift │ └── DottingAroundSquareView.swift ├── DottingAroundTriangle │ ├── DottingAroundTriangleActivityIndicatorView.swift │ ├── DottingAroundTriangleTimeline.swift │ └── DottingAroundTriangleView.swift ├── DoubleTime │ ├── DoubleTimeActivityIndicatorView.swift │ ├── DoubleTimeTimeline.swift │ └── DoubleTimeView.swift ├── Fire │ ├── FireActivityIndicatorView.swift │ ├── FireTimeline.swift │ └── FireView.swift ├── FlowWheel │ ├── FlowWheelActivityIndicatorView.swift │ ├── FlowWheelTimeline.swift │ └── FlowWheelView.swift ├── GradientRingActivityIndicatorView.swift ├── GradientRingTimeline.swift ├── GradientRingView.swift ├── Griddy │ ├── GriddyActivityIndicatorView.swift │ ├── GriddyTimeline.swift │ └── GriddyView.swift ├── Gridlock │ ├── GridlockActivityIndicatorView.swift │ ├── GridlockTimeline.swift │ └── GridlockView.swift ├── Hal │ ├── HalActivityIndicatorView.swift │ ├── HalTimeline.swift │ └── HalView.swift ├── Hexa │ ├── HexaActivityIndicatorView.swift │ ├── HexaTimeline.swift │ └── HexaView.swift ├── Hicks │ ├── HicksActivityIndicatorView.swift │ ├── HicksTimeline.swift │ └── HicksView.swift ├── Infinity │ ├── InfinityActivityIndicatorView.swift │ ├── InfinityTimeline.swift │ └── InfinityView.swift ├── Magician │ ├── MagicianActivityIndicatorView.swift │ ├── MagicianTimeline.swift │ └── MagicianView.swift ├── Mountains │ ├── MountainsActivityIndicatorView.swift │ ├── MountainsTimeline.swift │ └── MountainsView.swift ├── MoveAlong │ ├── MoveAlongActivityIndicatorView.swift │ ├── MoveAlongTimeline.swift │ └── MoveAlongView.swift ├── Nonover │ ├── NonoverActivityIndicatorView.swift │ ├── NonoverTimeline.swift │ └── NonoverView.swift ├── Overlapping │ ├── OverlappingActivityIndicatorView.swift │ ├── OverlappingTimeline.swift │ └── OverlappingView.swift ├── Penta │ ├── PentaActivityIndicatorView.swift │ ├── PentaTimeline.swift │ └── PentaView.swift ├── Quarbit │ ├── QuarbitActivityIndicatorView.swift │ ├── QuarbitTimeline.swift │ └── QuarbitView.swift ├── Queued │ ├── QueuedActivityIndicatorView.swift │ ├── QueuedTimeline.swift │ └── QueuedView.swift ├── Rainbow │ ├── RainbowActivityIndicatorView.swift │ ├── RainbowTimeline.swift │ └── RainbowView.swift ├── Reflect │ ├── ReflectActivityIndicatorView.swift │ ├── ReflectTimeline.swift │ └── ReflectView.swift ├── RingItIn │ ├── RingItInActivityIndicatorView.swift │ ├── RingItInTimeline.swift │ └── RingItInView.swift ├── Ripley │ ├── RipleyActivityIndicatorView.swift │ ├── RipleyTimeline.swift │ └── RipleyView.swift ├── Roulette │ ├── RouletteActivityIndicatorView.swift │ ├── RouletteTimeline.swift │ └── RouletteView.swift ├── ShiftDrift │ ├── ShiftDriftActivityIndicatorView.swift │ ├── ShiftDriftTimeline.swift │ └── ShiftDriftView.swift ├── Shkwv │ ├── ShkwvActivityIndicatorView.swift │ ├── ShkwvTimeline.swift │ └── ShkwvView.swift ├── ShowingUp │ ├── ShowingUpActivityIndicatorView.swift │ ├── ShowingUpTimeline.swift │ └── ShowingUpView.swift ├── Skeu │ ├── SkeuActivityIndicatorView.swift │ ├── SkeuTimeline.swift │ └── SkeuView.swift ├── SpinUp │ ├── SpinUpActivityIndicatorView.swift │ ├── SpinUpTimeline.swift │ └── SpinUpView.swift ├── Spindle │ ├── SpindleActivityIndicatorView.swift │ ├── SpindleTimeline.swift │ └── SpindleView.swift ├── Spinning │ ├── SpinningActivityIndicatorView.swift │ ├── SpinningTimeline.swift │ └── SpinningView.swift ├── Splayed │ ├── SplayedActivityIndicatorView.swift │ ├── SplayedTimeline.swift │ └── SplayedView.swift ├── SquareUp │ ├── SquareUpActivityIndicatorView.swift │ ├── SquareUpTimeline.swift │ └── SquareUpView.swift ├── StandBy │ ├── StandByActivityIndicatorView.swift │ ├── StandByTimeline.swift │ └── StandByView.swift ├── StretchAround │ ├── StretchAroundActivityIndicatorView.swift │ ├── StretchAroundTimeline.swift │ └── StretchAroundView.swift ├── Triplex │ ├── TriplexActivityIndicatorView.swift │ ├── TriplexTimeline.swift │ └── TriplexView.swift ├── Tumble │ ├── TumbleActivityIndicatorView.swift │ ├── TumbleTimeline.swift │ └── TumbleView.swift └── Xact │ ├── XactActivityIndicatorView.swift │ ├── XactTimeline.swift │ └── XactView.swift ├── AppDelegate.swift ├── FlowCommon ├── Animation.swift ├── CAKeyframeAnimation+Extension.swift ├── CAMediaTimingFunction+Extension.swift ├── CATransaction+Extension.swift ├── CGPath+SVG.swift ├── NSMutableParagraphStyle+Extension.swift ├── NSShadow+Extension.swift ├── ShapeView.swift ├── Sound.swift ├── TextView.swift ├── Timeline.swift ├── UIImage+Extension.swift └── UIView+Extension.swift ├── LaunchAnimation ├── LaunchAnimationTimeline.swift ├── LaunchAnimationView.swift └── LaunchAnimationViewController.swift └── ViewController.swift /ActivityIndicatorView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ActivityIndicatorView.xcodeproj/xcshareddata/xcschemes/ActivityIndicatorView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Assets/demo.gif -------------------------------------------------------------------------------- /Assets/flow-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Assets/flow-logo@2x.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Flow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-42.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-60.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-59.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-87.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-81.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-121.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-120.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-180.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-20.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-41.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-29.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-58.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-80.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-152.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-167.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "Icon-1024.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "flow" 115 | } 116 | } -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-120.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-121.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-121.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-152.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-167.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-180.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-20.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-29.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-41.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-42.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-58.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-59.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-60.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-80.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-81.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/AppIcon.appiconset/Icon-87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/AppIcon.appiconset/Icon-87.png -------------------------------------------------------------------------------- /Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Resources/Assets.xcassets/FlowWordmark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "FlowWordmark.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Resources/Assets.xcassets/FlowWordmark.imageset/FlowWordmark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/createwithflow/ActivityIndicatorView/26b3b49b55c578591a9b1b3091418f92fa930fc8/Resources/Assets.xcassets/FlowWordmark.imageset/FlowWordmark.pdf -------------------------------------------------------------------------------- /Resources/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Spinners 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | FlowVersion 26 | 1.9.0 27 | LSRequiresIPhoneOS 28 | 29 | UIAppFonts 30 | 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UIStatusBarHidden 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | UISupportedInterfaceOrientations~ipad 48 | 49 | UIInterfaceOrientationPortrait 50 | UIInterfaceOrientationPortraitUpsideDown 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Sources/ActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ActivityIndicatorView.swift 3 | // Loader 4 | // 5 | // Created by Travis on 2020-04-15. 6 | // Copyright © 2020 Travis. All rights reserved. 7 | // 8 | import Foundation 9 | import UIKit 10 | 11 | class ActivityIndicatorView: UIActivityIndicatorView { 12 | public private(set) var view: UIView! 13 | 14 | override func didMoveToSuperview() { 15 | handleAnimating() 16 | } 17 | 18 | var timeline: Timeline? { 19 | return nil 20 | } 21 | 22 | public override init(frame: CGRect) { 23 | super.init(frame: frame) 24 | setup() 25 | } 26 | 27 | public required init(coder aDecoder: NSCoder) { 28 | super.init(coder: aDecoder) 29 | setup() 30 | } 31 | 32 | public func createView() -> UIView { 33 | return UIView(frame: CGRect.null) 34 | } 35 | 36 | //add the animation view 37 | private func setup() { 38 | view = createView() 39 | layer.backgroundColor = UIColor.clear.cgColor 40 | layer.shadowRadius = 4 41 | layer.masksToBounds = false 42 | layer.shadowRadius = 2 43 | layer.shadowOpacity = 0.25 44 | layer.shadowColor = UIColor.black.cgColor 45 | layer.shadowOffset = CGSize(width: 0, height: 2) 46 | addSubview(view) 47 | } 48 | 49 | /// Used for when launching from interface builder, checks the state and automatically plays 50 | func handleAnimating() { 51 | if isAnimating { 52 | timeline?.play() 53 | } 54 | } 55 | 56 | override func startAnimating() { 57 | super.startAnimating() 58 | timeline?.play() 59 | } 60 | 61 | override func stopAnimating() { 62 | super.stopAnimating() 63 | timeline?.pause() 64 | timeline?.offset(to: 0) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Sources/Animations/Barista/BaristaActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class BaristaActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var barista: BaristaView = { 11 | let startView = BaristaView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return BaristaTimeline(view: barista, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return barista 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Animations/Breathe/BreatheActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class BreatheActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var breathe: BreatheView = { 11 | let startView = BreatheView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return BreatheTimeline(view: breathe, duration: 4.05, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return breathe 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Breathe/BreatheTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class BreatheTimeline: Timeline { 9 | public convenience init(view: BreatheView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = BreatheTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: BreatheView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for breath 15 | let bounds_size_width_breath: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "bounds.size.width" 18 | keyframeAnimation.values = [3, 28, 3, 3, 28, 28, 3, 3] 19 | keyframeAnimation.keyTimes = [0, 0.246914, 0.493827, 0.506173, 0.740741, 0.753086, 0.987654, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut, CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let bounds_size_height_breath: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "bounds.size.height" 28 | keyframeAnimation.values = [3, 3, 28, 28, 3, 28, 3, 3] 29 | keyframeAnimation.keyTimes = [0, 0.0123457, 0.246914, 0.259259, 0.493827, 0.740741, 0.987654, 1] 30 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | let path_breath: CAKeyframeAnimation = { 36 | let keyframeAnimation = CAKeyframeAnimation() 37 | keyframeAnimation.keyPath = "path" 38 | keyframeAnimation.values = [CGPathCreateWithSVGString("M1.5,3c0.828,0,1.5,-0.672,1.5,-1.5 0,-0.828,-0.672,-1.5,-1.5,-1.5 -0.828,0,-1.5,0.672,-1.5,1.5 0,0.828,0.672,1.5,1.5,1.5zM1.5,3")!, CGPathCreateWithSVGString("M4.261,3c2.353,0,4.261,-0.672,4.261,-1.5 0,-0.828,-1.908,-1.5,-4.261,-1.5 -2.353,0,-4.261,0.672,-4.261,1.5 0,0.828,1.908,1.5,4.261,1.5zM4.261,3")!, CGPathCreateWithSVGString("M14,28c7.732,0,14,-6.268,14,-14 0,-7.732,-6.268,-14,-14,-14 -7.732,0,-14,6.268,-14,14 0,7.732,6.268,14,14,14zM14,28")!, CGPathCreateWithSVGString("M11.239,28c6.207,0,11.239,-6.268,11.239,-14 0,-7.732,-5.032,-14,-11.239,-14 -6.207,0,-11.239,6.268,-11.239,14 0,7.732,5.032,14,11.239,14zM11.239,28")!, CGPathCreateWithSVGString("M1.5,3c0.828,0,1.5,-0.672,1.5,-1.5 0,-0.828,-0.672,-1.5,-1.5,-1.5 -0.828,0,-1.5,0.672,-1.5,1.5 0,0.828,0.672,1.5,1.5,1.5zM1.5,3")!, CGPathCreateWithSVGString("M1.5,8.521c0.828,0,1.5,-1.908,1.5,-4.261 0,-2.353,-0.672,-4.261,-1.5,-4.261 -0.828,0,-1.5,1.908,-1.5,4.261 0,2.353,0.672,4.261,1.5,4.261zM1.5,8.521")!, CGPathCreateWithSVGString("M14,28c7.732,0,14,-6.268,14,-14 0,-7.732,-6.268,-14,-14,-14 -7.732,0,-14,6.268,-14,14 0,7.732,6.268,14,14,14zM14,28")!, CGPathCreateWithSVGString("M14,22.479c7.732,0,14,-5.032,14,-11.239 0,-6.207,-6.268,-11.239,-14,-11.239 -7.732,0,-14,5.032,-14,11.239 0,6.207,6.268,11.239,14,11.239zM14,22.479")!, CGPathCreateWithSVGString("M1.5,3c0.828,0,1.5,-0.672,1.5,-1.5 0,-0.828,-0.672,-1.5,-1.5,-1.5 -0.828,0,-1.5,0.672,-1.5,1.5 0,0.828,0.672,1.5,1.5,1.5zM1.5,3")!, CGPathCreateWithSVGString("M1.5,3c0.828,0,1.5,-0.672,1.5,-1.5 0,-0.828,-0.672,-1.5,-1.5,-1.5 -0.828,0,-1.5,0.672,-1.5,1.5 0,0.828,0.672,1.5,1.5,1.5zM1.5,3")!] 39 | keyframeAnimation.keyTimes = [0, 0.0123457, 0.246914, 0.259259, 0.493827, 0.506173, 0.740741, 0.753086, 0.987654, 1] 40 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut] 41 | keyframeAnimation.duration = duration 42 | 43 | return keyframeAnimation 44 | }() 45 | 46 | // Organize CAKeyframeAnimations by CALayer 47 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 48 | animationsByLayer[view.breath.layer] = [bounds_size_width_breath, path_breath, bounds_size_height_breath] 49 | 50 | return animationsByLayer 51 | } 52 | } -------------------------------------------------------------------------------- /Sources/Animations/Breathe/BreatheView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class BreatheView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var breath: ShapeView! 17 | 18 | public override var intrinsicContentSize: CGSize { 19 | return Defaults.size 20 | } 21 | 22 | public override init(frame: CGRect) { 23 | super.init(frame: frame) 24 | setup() 25 | } 26 | 27 | public required init?(coder: NSCoder) { 28 | super.init(coder: coder) 29 | setup() 30 | } 31 | 32 | private func setup() { 33 | createViews() 34 | addSubviews() 35 | //scale(to: frame.size) 36 | } 37 | 38 | /// Scales `self` and its subviews to `size`. 39 | /// 40 | /// - Parameter size: The size `self` is scaled to. 41 | /// 42 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 43 | /// calculates a view's alignment rectangle based on its untransformed frame." 44 | /// 45 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 46 | /// 47 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 48 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 49 | public func scale(to size: CGSize) { 50 | let x = size.width / Defaults.size.width 51 | let y = size.height / Defaults.size.height 52 | transform = CGAffineTransform(scaleX: x, y: y) 53 | } 54 | 55 | private func createViews() { 56 | CATransaction.suppressAnimations { 57 | createSceneContainer() 58 | createBreath() 59 | } 60 | } 61 | 62 | private func createSceneContainer() { 63 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 64 | sceneContainer.backgroundColor = Defaults.backgroundColor 65 | sceneContainer.layer.cornerRadius = 5.0 66 | sceneContainer.layer.masksToBounds = true 67 | } 68 | 69 | private func createBreath() { 70 | breath = ShapeView(frame: CGRect(x: 18.5, y: 18.5, width: 3, height: 3)) 71 | breath.backgroundColor = UIColor.clear 72 | breath.layer.shadowOffset = CGSize(width: 0, height: 0) 73 | breath.layer.shadowColor = UIColor.clear.cgColor 74 | breath.layer.shadowOpacity = 1 75 | breath.layer.position = CGPoint(x: 18.5, y: 18.5) 76 | breath.layer.bounds = CGRect(x: 0, y: 0, width: 3, height: 3) 77 | breath.layer.masksToBounds = false 78 | breath.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 79 | breath.shapeLayer.strokeColor = UIColor(red: 0.22, green: 0.282, blue: 0.353, alpha: 1).cgColor 80 | breath.shapeLayer.fillColor = UIColor(red: 0.314, green: 0.89, blue: 0.761, alpha: 1).cgColor 81 | breath.shapeLayer.lineDashPattern = [] 82 | breath.shapeLayer.lineDashPhase = 0 83 | breath.shapeLayer.lineWidth = 3 84 | breath.shapeLayer.path = CGPathCreateWithSVGString("M1.5,3c0.828,0,1.5,-0.672,1.5,-1.5 0,-0.828,-0.672,-1.5,-1.5,-1.5 -0.828,0,-1.5,0.672,-1.5,1.5 0,0.828,0.672,1.5,1.5,1.5zM1.5,3")! 85 | 86 | } 87 | 88 | private func addSubviews() { 89 | sceneContainer.addSubview(breath) 90 | addSubview(sceneContainer) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Sources/Animations/Caught/CaughtActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class CaughtActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var caught: CaughtView = { 11 | let startView = CaughtView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return CaughtTimeline(view: caught, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return caught 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Caught/CaughtTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class CaughtTimeline: Timeline { 9 | public convenience init(view: CaughtView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = CaughtTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: CaughtView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for dot 15 | let position_x_dot: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "position.x" 18 | keyframeAnimation.values = [18.5, 26.81, 5.81, 31.19, 10.19, 18.5] 19 | keyframeAnimation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] 20 | keyframeAnimation.timingFunctions = [.easeOut, .easeOut, .easeIn, .easeIn, .easeIn] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let position_y_dot: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "position.y" 28 | keyframeAnimation.values = [4.94, 30.31, 15.45, 15.45, 30.31, 4.94] 29 | keyframeAnimation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] 30 | keyframeAnimation.timingFunctions = [.easeIn, .easeIn, .easeIn, .easeOut, .easeOut] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | 36 | // Organize CAKeyframeAnimations by CALayer 37 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 38 | animationsByLayer[view.dot.layer] = [position_x_dot, position_y_dot] 39 | 40 | return animationsByLayer 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Animations/Caught/CaughtView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class CaughtView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor.white 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var bigDot: ShapeView! 17 | public var dot: ShapeView! 18 | 19 | public override var intrinsicContentSize: CGSize { 20 | return Defaults.size 21 | } 22 | 23 | public override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | public required init?(coder: NSCoder) { 29 | super.init(coder: coder) 30 | setup() 31 | } 32 | 33 | private func setup() { 34 | createViews() 35 | addSubviews() 36 | //scale(to: frame.size) 37 | } 38 | 39 | /// Scales `self` and its subviews to `size`. 40 | /// 41 | /// - Parameter size: The size `self` is scaled to. 42 | /// 43 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 44 | /// calculates a view's alignment rectangle based on its untransformed frame." 45 | /// 46 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 47 | /// 48 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 49 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 50 | public func scale(to size: CGSize) { 51 | let x = size.width / Defaults.size.width 52 | let y = size.height / Defaults.size.height 53 | transform = CGAffineTransform(scaleX: x, y: y) 54 | } 55 | 56 | private func createViews() { 57 | CATransaction.suppressAnimations { 58 | createSceneContainer() 59 | createBigDot() 60 | createDot() 61 | } 62 | } 63 | 64 | private func createSceneContainer() { 65 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 66 | sceneContainer.backgroundColor = Defaults.backgroundColor 67 | sceneContainer.layer.cornerRadius = 5.0 68 | sceneContainer.layer.masksToBounds = true 69 | } 70 | 71 | private func createBigDot() { 72 | bigDot = ShapeView(frame: CGRect(x: 18.5, y: 18.5, width: 28, height: 28)) 73 | bigDot.backgroundColor = UIColor.clear 74 | bigDot.layer.shadowOffset = CGSize(width: 0, height: 0) 75 | bigDot.layer.shadowColor = UIColor.clear.cgColor 76 | bigDot.layer.shadowOpacity = 1 77 | bigDot.layer.position = CGPoint(x: 18.5, y: 18.5) 78 | bigDot.layer.bounds = CGRect(x: 0, y: 0, width: 28, height: 28) 79 | bigDot.layer.masksToBounds = false 80 | bigDot.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 81 | bigDot.shapeLayer.strokeColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1).cgColor 82 | bigDot.shapeLayer.fillColor = UIColor(red: 0.199, green: 0.827, blue: 0.936, alpha: 1).cgColor 83 | bigDot.shapeLayer.lineDashPattern = [] 84 | bigDot.shapeLayer.lineDashPhase = 0 85 | bigDot.shapeLayer.lineWidth = 3 86 | bigDot.shapeLayer.path = CGPathCreateWithSVGString("M14,28c7.732,0,14,-6.268,14,-14 0,-7.732,-6.268,-14,-14,-14 -7.732,0,-14,6.268,-14,14 0,7.732,6.268,14,14,14zM14,28")! 87 | 88 | } 89 | 90 | private func createDot() { 91 | dot = ShapeView(frame: CGRect(x: 18.5, y: 4.94, width: 5.25, height: 5.25)) 92 | dot.backgroundColor = UIColor.clear 93 | dot.layer.shadowOffset = CGSize(width: 0, height: 0) 94 | dot.layer.shadowColor = UIColor.clear.cgColor 95 | dot.layer.shadowOpacity = 1 96 | dot.layer.position = CGPoint(x: 18.5, y: 4.94) 97 | dot.layer.bounds = CGRect(x: 0, y: 0, width: 5.25, height: 5.25) 98 | dot.layer.masksToBounds = false 99 | dot.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 100 | dot.shapeLayer.strokeColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1).cgColor 101 | dot.shapeLayer.fillColor = UIColor.white.cgColor 102 | dot.shapeLayer.lineDashPattern = [] 103 | dot.shapeLayer.lineDashPhase = 0 104 | dot.shapeLayer.lineWidth = 3 105 | dot.shapeLayer.path = CGPathCreateWithSVGString("M2.625,5.25c1.45,0,2.625,-1.175,2.625,-2.625 0,-1.45,-1.175,-2.625,-2.625,-2.625 -1.45,0,-2.625,1.175,-2.625,2.625 0,1.45,1.175,2.625,2.625,2.625zM2.625,5.25")! 106 | 107 | } 108 | 109 | private func addSubviews() { 110 | sceneContainer.addSubview(bigDot) 111 | sceneContainer.addSubview(dot) 112 | addSubview(sceneContainer) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Sources/Animations/Charting/ChartingActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class ChartingActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var charting: ChartingView = { 11 | let startView = ChartingView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return ChartingTimeline(view: charting, duration: 4, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return charting 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Charting/ChartingTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class ChartingTimeline: Timeline { 9 | public convenience init(view: ChartingView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = ChartingTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: ChartingView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for group 15 | let transform_rotation_z_group: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, 6.28319] 19 | keyframeAnimation.keyTimes = [0, 1] 20 | keyframeAnimation.timingFunctions = [.linear] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for pi0 27 | let strokeend_pi0: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "strokeEnd" 30 | keyframeAnimation.values = [1.001, 1.001, 0] 31 | keyframeAnimation.keyTimes = [0, 0.75, 1] 32 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1)] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | 38 | // Keyframe Animations for pi1 39 | let strokeend_pi1: CAKeyframeAnimation = { 40 | let keyframeAnimation = CAKeyframeAnimation() 41 | keyframeAnimation.keyPath = "strokeEnd" 42 | keyframeAnimation.values = [1.001, 1.001, 0, 0] 43 | keyframeAnimation.keyTimes = [0, 0.5, 0.75, 1] 44 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut] 45 | keyframeAnimation.duration = duration 46 | 47 | return keyframeAnimation 48 | }() 49 | 50 | // Keyframe Animations for pi2 51 | let strokeend_pi2: CAKeyframeAnimation = { 52 | let keyframeAnimation = CAKeyframeAnimation() 53 | keyframeAnimation.keyPath = "strokeEnd" 54 | keyframeAnimation.values = [1.001, 1.001, 0, 0] 55 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 1] 56 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut] 57 | keyframeAnimation.duration = duration 58 | 59 | return keyframeAnimation 60 | }() 61 | 62 | // Keyframe Animations for pi3 63 | let strokeend_pi3: CAKeyframeAnimation = { 64 | let keyframeAnimation = CAKeyframeAnimation() 65 | keyframeAnimation.keyPath = "strokeEnd" 66 | keyframeAnimation.values = [1.001, 0, 0] 67 | keyframeAnimation.keyTimes = [0, 0.25, 1] 68 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.165, 0.84, 0.44, 1), .easeInEaseOut] 69 | keyframeAnimation.duration = duration 70 | 71 | return keyframeAnimation 72 | }() 73 | 74 | // Organize CAKeyframeAnimations by CALayer 75 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 76 | animationsByLayer[view.pi1.layer] = [strokeend_pi1] 77 | animationsByLayer[view.group.layer] = [transform_rotation_z_group] 78 | animationsByLayer[view.pi3.layer] = [strokeend_pi3] 79 | animationsByLayer[view.pi0.layer] = [strokeend_pi0] 80 | animationsByLayer[view.pi2.layer] = [strokeend_pi2] 81 | 82 | return animationsByLayer 83 | } 84 | } -------------------------------------------------------------------------------- /Sources/Animations/Compass/CompassActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class CompassActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var compass: CompassView = { 11 | let startView = CompassView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return CompassTimeline(view: compass, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return compass 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Compass/CompassTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class CompassTimeline: Timeline { 9 | public convenience init(view: CompassView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = CompassTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: CompassView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for compassNeedle 15 | let transform_rotation_z_compassNeedle: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, -0.383972, 6.28319, 6.28319] 19 | keyframeAnimation.keyTimes = [0, 0.2, 0.8, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.175, 0.885, 0.32, 1.275), .easeInEaseOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Organize CAKeyframeAnimations by CALayer 27 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 28 | animationsByLayer[view.compassNeedle.layer] = [transform_rotation_z_compassNeedle] 29 | 30 | return animationsByLayer 31 | } 32 | } -------------------------------------------------------------------------------- /Sources/Animations/Cradle/CradleActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class CradleActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var cradle: CradleView = { 11 | let startView = CradleView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return CradleTimeline(view: cradle, duration: 1.5, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return cradle 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Animations/Dashed/DashedActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DashedActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var dashed: DashedView = { 11 | let startView = DashedView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DashedTimeline(view: dashed, duration: 2.4, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return dashed 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Dashed/DashedTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class DashedTimeline: Timeline { 9 | public convenience init(view: DashedView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = DashedTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: DashedView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for d 15 | let transform_rotation_z_d: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, 0, -4.71239, -6.28319, -6.54498, -6.28319, -6.28319] 19 | keyframeAnimation.keyTimes = [0, 0.5, 0.666667, 0.75, 0.8125, 0.875, 1] 20 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0, 0.175315, 0.646025, 0.997312), .easeIn, .easeOut, .easeOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for c 27 | let transform_rotation_z_c: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "transform.rotation.z" 30 | keyframeAnimation.values = [0, 0, 3.40339, 3.14159, 3.14159, -3.14159, 0.261799, 0, 0] 31 | keyframeAnimation.keyTimes = [0, 0.370833, 0.55, 0.620833, 0.7375, 0.741667, 0.920833, 0.991667, 1] 32 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut, .linear, .linear, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | 38 | // Keyframe Animations for b 39 | let transform_rotation_z_b: CAKeyframeAnimation = { 40 | let keyframeAnimation = CAKeyframeAnimation() 41 | keyframeAnimation.keyPath = "transform.rotation.z" 42 | keyframeAnimation.values = [0.288677, -0.261799, 0, 0, -3.40339, -3.14159, -3.14159, 3.14159, 0.288677] 43 | keyframeAnimation.keyTimes = [0, 0.0458333, 0.120833, 0.241667, 0.420833, 0.491667, 0.866667, 0.870833, 1] 44 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.249163, -0.0012543, 0.58, 1), .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .linear, .linear, CAMediaTimingFunction(controlPoints: 0.42, 0, 0.768546, 0.999194)] 45 | keyframeAnimation.duration = duration 46 | 47 | return keyframeAnimation 48 | }() 49 | 50 | // Keyframe Animations for a 51 | let transform_rotation_z_a: CAKeyframeAnimation = { 52 | let keyframeAnimation = CAKeyframeAnimation() 53 | keyframeAnimation.keyPath = "transform.rotation.z" 54 | keyframeAnimation.values = [0, 4.71239, 6.28319, 6.54498, 6.28319, 6.28319] 55 | keyframeAnimation.keyTimes = [0, 0.166667, 0.25, 0.3125, 0.375, 1] 56 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0, 0.175315, 0.646025, 0.997312), .easeIn, .easeOut, .easeOut, .linear] 57 | keyframeAnimation.duration = duration 58 | 59 | return keyframeAnimation 60 | }() 61 | 62 | // Organize CAKeyframeAnimations by CALayer 63 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 64 | animationsByLayer[view.b.layer] = [transform_rotation_z_b] 65 | animationsByLayer[view.a.layer] = [transform_rotation_z_a] 66 | animationsByLayer[view.c.layer] = [transform_rotation_z_c] 67 | animationsByLayer[view.d.layer] = [transform_rotation_z_d] 68 | 69 | return animationsByLayer 70 | } 71 | } -------------------------------------------------------------------------------- /Sources/Animations/Deceptive/DeceptiveActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DeceptiveActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var deceptive: DeceptiveView = { 11 | let startView = DeceptiveView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DeceptiveTimeline(view: deceptive, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return deceptive 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Deceptive/DeceptiveTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class DeceptiveTimeline: Timeline { 9 | public convenience init(view: DeceptiveView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = DeceptiveTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: DeceptiveView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for group 15 | let transform_rotation_z_group: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, 1.5708, 3.14159, 4.71239, 6.28319] 19 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 20 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for bigDot 27 | let position_x_bigDot: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.x" 30 | keyframeAnimation.values = [0, 0, 14, 14, 0, 0, 14, 14, 0] 31 | keyframeAnimation.keyTimes = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] 32 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | let position_y_bigDot: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.y" 40 | keyframeAnimation.values = [14, 0, 0, 14, 14, 0, 0, 14, 14] 41 | keyframeAnimation.keyTimes = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] 42 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | 48 | // Organize CAKeyframeAnimations by CALayer 49 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 50 | animationsByLayer[view.bigDot.layer] = [position_x_bigDot, position_y_bigDot] 51 | animationsByLayer[view.group.layer] = [transform_rotation_z_group] 52 | 53 | return animationsByLayer 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Animations/Dialed/DialedActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DialedActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var dialed: DialedView = { 11 | let startView = DialedView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DialedTimeline(view: dialed, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return dialed 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Dialed/DialedTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class DialedTimeline: Timeline { 9 | public convenience init(view: DialedView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = DialedTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: DialedView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for dial 15 | let transform_rotation_z_dial: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, 6.28319] 19 | keyframeAnimation.keyTimes = [0, 1] 20 | keyframeAnimation.timingFunctions = [.linear] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for bars 27 | let position_x_bars: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.x" 30 | keyframeAnimation.values = [-34, 67] 31 | keyframeAnimation.keyTimes = [0, 1] 32 | keyframeAnimation.timingFunctions = [.linear] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | let position_y_bars: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.y" 40 | keyframeAnimation.values = [-36, 67] 41 | keyframeAnimation.keyTimes = [0, 1] 42 | keyframeAnimation.timingFunctions = [.linear] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | 48 | // Organize CAKeyframeAnimations by CALayer 49 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 50 | animationsByLayer[view.bars.layer] = [position_y_bars, position_x_bars] 51 | animationsByLayer[view.dial.layer] = [transform_rotation_z_dial] 52 | 53 | return animationsByLayer 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Animations/Differences/DifferencesActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DifferencesActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var differences: DifferencesView = { 11 | let startView = DifferencesView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DifferencesTimeline(view: differences, duration: 4, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return differences 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundCircle/DottingAroundCircleActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DottingAroundCircleActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var dottingAroundCircle: DottingAroundCircleView = { 11 | let startView = DottingAroundCircleView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DottingAroundCircleTimeline(view: dottingAroundCircle, duration: 3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return dottingAroundCircle 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundCircle/DottingAroundCircleTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class DottingAroundCircleTimeline: Timeline { 9 | public convenience init(view: DottingAroundCircleView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = DottingAroundCircleTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: DottingAroundCircleView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for circle 15 | let transform_rotation_z_circle: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [5.49779, 3.92699, 2.35619, 0.785398, -0.785398] 19 | keyframeAnimation.keyTimes = [0, 0.253333, 0.5, 0.753333, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for dot 27 | let position_x_dot: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.x" 30 | keyframeAnimation.values = [18.5, 31.5, 18.5, 5.5, 18.5] 31 | keyframeAnimation.keyTimes = [0, 0.253333, 0.5, 0.753333, 1] 32 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | let position_y_dot: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.y" 40 | keyframeAnimation.values = [31.74, 18.74, 5.74, 18.74, 31.74] 41 | keyframeAnimation.keyTimes = [0, 0.253333, 0.5, 0.753333, 1] 42 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | 48 | // Organize CAKeyframeAnimations by CALayer 49 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 50 | animationsByLayer[view.dot.layer] = [position_y_dot, position_x_dot] 51 | animationsByLayer[view.circle.layer] = [transform_rotation_z_circle] 52 | 53 | return animationsByLayer 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundCircle/DottingAroundCircleView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class DottingAroundCircleView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var circle: ShapeView! 17 | public var dot: ShapeView! 18 | 19 | public override var intrinsicContentSize: CGSize { 20 | return Defaults.size 21 | } 22 | 23 | public override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | public required init?(coder: NSCoder) { 29 | super.init(coder: coder) 30 | setup() 31 | } 32 | 33 | private func setup() { 34 | createViews() 35 | addSubviews() 36 | //scale(to: frame.size) 37 | } 38 | 39 | /// Scales `self` and its subviews to `size`. 40 | /// 41 | /// - Parameter size: The size `self` is scaled to. 42 | /// 43 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 44 | /// calculates a view's alignment rectangle based on its untransformed frame." 45 | /// 46 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 47 | /// 48 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 49 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 50 | public func scale(to size: CGSize) { 51 | let x = size.width / Defaults.size.width 52 | let y = size.height / Defaults.size.height 53 | transform = CGAffineTransform(scaleX: x, y: y) 54 | } 55 | 56 | private func createViews() { 57 | CATransaction.suppressAnimations { 58 | createSceneContainer() 59 | createCircle() 60 | createDot() 61 | } 62 | } 63 | 64 | private func createSceneContainer() { 65 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 66 | sceneContainer.backgroundColor = Defaults.backgroundColor 67 | sceneContainer.layer.cornerRadius = 5.0 68 | sceneContainer.layer.masksToBounds = true 69 | } 70 | 71 | private func createCircle() { 72 | circle = ShapeView(frame: CGRect(x: 18.5, y: 18.74, width: 26, height: 26)) 73 | circle.backgroundColor = UIColor.clear 74 | circle.transform = CGAffineTransform(rotationAngle: 1.75 * CGFloat.pi) 75 | circle.layer.shadowOffset = CGSize(width: 0, height: 0) 76 | circle.layer.shadowColor = UIColor.clear.cgColor 77 | circle.layer.shadowOpacity = 1 78 | circle.layer.position = CGPoint(x: 18.5, y: 18.74) 79 | circle.layer.bounds = CGRect(x: 0, y: 0, width: 26, height: 26) 80 | circle.layer.masksToBounds = false 81 | circle.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 82 | circle.shapeLayer.strokeColor = UIColor(red: 0.948, green: 0.948, blue: 0.948, alpha: 1).cgColor 83 | circle.shapeLayer.fillColor = nil 84 | circle.shapeLayer.lineCap = CAShapeLayerLineCap(rawValue: "round") 85 | circle.shapeLayer.lineJoin = CAShapeLayerLineJoin(rawValue: "round") 86 | circle.shapeLayer.strokeEnd = 0.75 87 | circle.shapeLayer.lineDashPattern = [] 88 | circle.shapeLayer.lineDashPhase = 0 89 | circle.shapeLayer.lineWidth = 6 90 | circle.shapeLayer.path = CGPathCreateWithSVGString("M13,26c7.18,0,13,-5.82,13,-13 0,-7.18,-5.82,-13,-13,-13 -7.18,0,-13,5.82,-13,13 0,7.18,5.82,13,13,13zM13,26")! 91 | 92 | } 93 | 94 | private func createDot() { 95 | dot = ShapeView(frame: CGRect(x: 18.5, y: 31.74, width: 6, height: 6)) 96 | dot.backgroundColor = UIColor.clear 97 | dot.layer.shadowOffset = CGSize(width: 0, height: 0) 98 | dot.layer.shadowColor = UIColor.clear.cgColor 99 | dot.layer.shadowOpacity = 1 100 | dot.layer.position = CGPoint(x: 18.5, y: 31.74) 101 | dot.layer.bounds = CGRect(x: 0, y: 0, width: 6, height: 6) 102 | dot.layer.masksToBounds = false 103 | dot.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 104 | dot.shapeLayer.fillColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1).cgColor 105 | dot.shapeLayer.lineDashPattern = [] 106 | dot.shapeLayer.lineDashPhase = 0 107 | dot.shapeLayer.lineWidth = 0 108 | dot.shapeLayer.path = CGPathCreateWithSVGString("M3,6c1.657,0,3,-1.343,3,-3 0,-1.657,-1.343,-3,-3,-3 -1.657,0,-3,1.343,-3,3 0,1.657,1.343,3,3,3zM3,6")! 109 | 110 | } 111 | 112 | private func addSubviews() { 113 | sceneContainer.addSubview(circle) 114 | sceneContainer.addSubview(dot) 115 | addSubview(sceneContainer) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundSquare/DottingAroundSquareActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DottingAroundSquareActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var dottingAroundSquare: DottingAroundSquareView = { 11 | let startView = DottingAroundSquareView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DottingAroundSquareTimeline(view: dottingAroundSquare, duration: 3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return dottingAroundSquare 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundSquare/DottingAroundSquareTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class DottingAroundSquareTimeline: Timeline { 9 | public convenience init(view: DottingAroundSquareView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = DottingAroundSquareTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: DottingAroundSquareView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for square 15 | let linedashphase_square: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "lineDashPhase" 18 | keyframeAnimation.values = [0, -24, -47.99, -71.99, -95.99] 19 | keyframeAnimation.keyTimes = [0, 0.253333, 0.5, 0.753333, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for dot 27 | let position_x_dot: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.x" 30 | keyframeAnimation.values = [18.5, 30.5, 18.5, 6.5, 18.5] 31 | keyframeAnimation.keyTimes = [0, 0.253333, 0.5, 0.753333, 1] 32 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | let position_y_dot: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.y" 40 | keyframeAnimation.values = [30.84, 18.84, 6.83, 18.84, 30.84] 41 | keyframeAnimation.keyTimes = [0, 0.253333, 0.5, 0.753333, 1] 42 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | 48 | // Organize CAKeyframeAnimations by CALayer 49 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 50 | animationsByLayer[view.dot.layer] = [position_y_dot, position_x_dot] 51 | animationsByLayer[view.square.layer] = [linedashphase_square] 52 | 53 | return animationsByLayer 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundSquare/DottingAroundSquareView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class DottingAroundSquareView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var square: ShapeView! 17 | public var dot: ShapeView! 18 | 19 | public override var intrinsicContentSize: CGSize { 20 | return Defaults.size 21 | } 22 | 23 | public override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | public required init?(coder: NSCoder) { 29 | super.init(coder: coder) 30 | setup() 31 | } 32 | 33 | private func setup() { 34 | createViews() 35 | addSubviews() 36 | //scale(to: frame.size) 37 | } 38 | 39 | /// Scales `self` and its subviews to `size`. 40 | /// 41 | /// - Parameter size: The size `self` is scaled to. 42 | /// 43 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 44 | /// calculates a view's alignment rectangle based on its untransformed frame." 45 | /// 46 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 47 | /// 48 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 49 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 50 | public func scale(to size: CGSize) { 51 | let x = size.width / Defaults.size.width 52 | let y = size.height / Defaults.size.height 53 | transform = CGAffineTransform(scaleX: x, y: y) 54 | } 55 | 56 | private func createViews() { 57 | CATransaction.suppressAnimations { 58 | createSceneContainer() 59 | createSquare() 60 | createDot() 61 | } 62 | } 63 | 64 | private func createSceneContainer() { 65 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 66 | sceneContainer.backgroundColor = Defaults.backgroundColor 67 | sceneContainer.layer.cornerRadius = 5.0 68 | sceneContainer.layer.masksToBounds = true 69 | } 70 | 71 | private func createSquare() { 72 | square = ShapeView(frame: CGRect(x: 18.5, y: 18.84, width: 24, height: 24)) 73 | square.backgroundColor = UIColor.clear 74 | square.layer.shadowOffset = CGSize(width: 0, height: 0) 75 | square.layer.shadowColor = UIColor.clear.cgColor 76 | square.layer.shadowOpacity = 1 77 | square.layer.position = CGPoint(x: 18.5, y: 18.84) 78 | square.layer.bounds = CGRect(x: 0, y: 0, width: 24, height: 24) 79 | square.layer.masksToBounds = false 80 | square.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 81 | square.shapeLayer.strokeColor = UIColor(red: 0.948, green: 0.948, blue: 0.948, alpha: 1).cgColor 82 | square.shapeLayer.fillColor = nil 83 | square.shapeLayer.lineCap = CAShapeLayerLineCap(rawValue: "round") 84 | square.shapeLayer.lineJoin = CAShapeLayerLineJoin(rawValue: "round") 85 | square.shapeLayer.lineDashPattern = [71.99, 24] 86 | square.shapeLayer.lineDashPhase = 0 87 | square.shapeLayer.lineWidth = 6 88 | square.shapeLayer.path = CGPathCreateWithSVGString("M24,24l0,-24 -24,0 0,24 24,0zM24,24")! 89 | 90 | } 91 | 92 | private func createDot() { 93 | dot = ShapeView(frame: CGRect(x: 18.5, y: 30.84, width: 6, height: 6)) 94 | dot.backgroundColor = UIColor.clear 95 | dot.layer.shadowOffset = CGSize(width: 0, height: 0) 96 | dot.layer.shadowColor = UIColor.clear.cgColor 97 | dot.layer.shadowOpacity = 1 98 | dot.layer.position = CGPoint(x: 18.5, y: 30.84) 99 | dot.layer.bounds = CGRect(x: 0, y: 0, width: 6, height: 6) 100 | dot.layer.masksToBounds = false 101 | dot.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 102 | dot.shapeLayer.fillColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1).cgColor 103 | dot.shapeLayer.lineDashPattern = [] 104 | dot.shapeLayer.lineDashPhase = 0 105 | dot.shapeLayer.lineWidth = 0 106 | dot.shapeLayer.path = CGPathCreateWithSVGString("M3,6c1.657,0,3,-1.343,3,-3 0,-1.657,-1.343,-3,-3,-3 -1.657,0,-3,1.343,-3,3 0,1.657,1.343,3,3,3zM3,6")! 107 | 108 | } 109 | 110 | private func addSubviews() { 111 | sceneContainer.addSubview(square) 112 | sceneContainer.addSubview(dot) 113 | addSubview(sceneContainer) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundTriangle/DottingAroundTriangleActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DottingAroundTriangleActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var dottingAroundTriangle: DottingAroundTriangleView = { 11 | let startView = DottingAroundTriangleView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DottingAroundTriangleTimeline(view: dottingAroundTriangle, duration: 3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return dottingAroundTriangle 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundTriangle/DottingAroundTriangleTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class DottingAroundTriangleTimeline: Timeline { 9 | public convenience init(view: DottingAroundTriangleView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = DottingAroundTriangleTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: DottingAroundTriangleView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for triangle 15 | let linedashphase_triangle: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "lineDashPhase" 18 | keyframeAnimation.values = [0, 26, 52, 78] 19 | keyframeAnimation.keyTimes = [0, 0.333333, 0.673333, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for dot 27 | let position_x_dot: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.x" 30 | keyframeAnimation.values = [12, 18.5, 25, 12] 31 | keyframeAnimation.keyTimes = [0, 0.333333, 0.673333, 1] 32 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | let position_y_dot: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.y" 40 | keyframeAnimation.values = [17.49, 28.83, 17.49, 17.49] 41 | keyframeAnimation.keyTimes = [0, 0.333333, 0.673333, 1] 42 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1), .easeInEaseOut] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | 48 | // Organize CAKeyframeAnimations by CALayer 49 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 50 | animationsByLayer[view.triangle.layer] = [linedashphase_triangle] 51 | animationsByLayer[view.dot.layer] = [position_y_dot, position_x_dot] 52 | 53 | return animationsByLayer 54 | } 55 | } -------------------------------------------------------------------------------- /Sources/Animations/DottingAroundTriangle/DottingAroundTriangleView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class DottingAroundTriangleView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var triangle: ShapeView! 17 | public var dot: ShapeView! 18 | 19 | public override var intrinsicContentSize: CGSize { 20 | return Defaults.size 21 | } 22 | 23 | public override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | public required init?(coder: NSCoder) { 29 | super.init(coder: coder) 30 | setup() 31 | } 32 | 33 | private func setup() { 34 | createViews() 35 | addSubviews() 36 | //scale(to: frame.size) 37 | } 38 | 39 | /// Scales `self` and its subviews to `size`. 40 | /// 41 | /// - Parameter size: The size `self` is scaled to. 42 | /// 43 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 44 | /// calculates a view's alignment rectangle based on its untransformed frame." 45 | /// 46 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 47 | /// 48 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 49 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 50 | public func scale(to size: CGSize) { 51 | let x = size.width / Defaults.size.width 52 | let y = size.height / Defaults.size.height 53 | transform = CGAffineTransform(scaleX: x, y: y) 54 | } 55 | 56 | private func createViews() { 57 | CATransaction.suppressAnimations { 58 | createSceneContainer() 59 | createTriangle() 60 | createDot() 61 | } 62 | } 63 | 64 | private func createSceneContainer() { 65 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 66 | sceneContainer.backgroundColor = Defaults.backgroundColor 67 | sceneContainer.layer.cornerRadius = 5.0 68 | sceneContainer.layer.masksToBounds = true 69 | } 70 | 71 | private func createTriangle() { 72 | triangle = ShapeView(frame: CGRect(x: 18.5, y: 17.49, width: 26, height: 22.65)) 73 | triangle.backgroundColor = UIColor.clear 74 | triangle.layer.shadowOffset = CGSize(width: 0, height: 0) 75 | triangle.layer.shadowColor = UIColor.clear.cgColor 76 | triangle.layer.shadowOpacity = 1 77 | triangle.layer.position = CGPoint(x: 18.5, y: 17.49) 78 | triangle.layer.bounds = CGRect(x: 0, y: 0, width: 26, height: 22.65) 79 | triangle.layer.masksToBounds = false 80 | triangle.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 81 | triangle.shapeLayer.strokeColor = UIColor(red: 0.948, green: 0.948, blue: 0.948, alpha: 1).cgColor 82 | triangle.shapeLayer.fillColor = nil 83 | triangle.shapeLayer.lineCap = CAShapeLayerLineCap(rawValue: "round") 84 | triangle.shapeLayer.lineJoin = CAShapeLayerLineJoin(rawValue: "round") 85 | triangle.shapeLayer.lineDashPattern = [52, 26] 86 | triangle.shapeLayer.lineDashPhase = 0 87 | triangle.shapeLayer.lineWidth = 6 88 | triangle.shapeLayer.path = CGPathCreateWithSVGString("M13,0l13,22.65 -26,0 13,-22.65zM13,0")! 89 | 90 | } 91 | 92 | private func createDot() { 93 | dot = ShapeView(frame: CGRect(x: 12, y: 17.49, width: 6, height: 6)) 94 | dot.backgroundColor = UIColor.clear 95 | dot.layer.shadowOffset = CGSize(width: 0, height: 0) 96 | dot.layer.shadowColor = UIColor.clear.cgColor 97 | dot.layer.shadowOpacity = 1 98 | dot.layer.position = CGPoint(x: 12, y: 17.49) 99 | dot.layer.bounds = CGRect(x: 0, y: 0, width: 6, height: 6) 100 | dot.layer.masksToBounds = false 101 | dot.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 102 | dot.shapeLayer.fillColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1).cgColor 103 | dot.shapeLayer.lineDashPattern = [] 104 | dot.shapeLayer.lineDashPhase = 0 105 | dot.shapeLayer.lineWidth = 0 106 | dot.shapeLayer.path = CGPathCreateWithSVGString("M3,6c1.657,0,3,-1.343,3,-3 0,-1.657,-1.343,-3,-3,-3 -1.657,0,-3,1.343,-3,3 0,1.657,1.343,3,3,3zM3,6")! 107 | 108 | } 109 | 110 | private func addSubviews() { 111 | sceneContainer.addSubview(triangle) 112 | sceneContainer.addSubview(dot) 113 | addSubview(sceneContainer) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/Animations/DoubleTime/DoubleTimeActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class DoubleTimeActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var doubleTime: DoubleTimeView = { 11 | let startView = DoubleTimeView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.22, green: 0.282, blue: 0.353, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return DoubleTimeTimeline(view: doubleTime, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return doubleTime 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Fire/FireActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class FireActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var fire: FireView = { 11 | let startView = FireView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return FireTimeline(view: fire, duration: 0.5, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return fire 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Fire/FireTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class FireTimeline: Timeline { 9 | public convenience init(view: FireView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = FireTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: FireView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for path 15 | let position_y_path: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "position.y" 18 | keyframeAnimation.values = [29, 28, 29, 28, 29] 19 | keyframeAnimation.keyTimes = [0, 0.42, 0.64, 0.84, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045), .easeInEaseOut, CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045), .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let transform_rotation_z_path: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "transform.rotation.z" 28 | keyframeAnimation.values = [0, 0.0523599, -0.0523599, 0] 29 | keyframeAnimation.keyTimes = [0, 0.34, 0.78, 1] 30 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | 36 | // Keyframe Animations for path_1 37 | let position_y_path_1: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.y" 40 | keyframeAnimation.values = [26, 25, 26, 25, 26] 41 | keyframeAnimation.keyTimes = [0, 0.34, 0.56, 0.78, 1] 42 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045), .easeInEaseOut, CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045), .easeInEaseOut] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | let transform_rotation_z_path_1: CAKeyframeAnimation = { 48 | let keyframeAnimation = CAKeyframeAnimation() 49 | keyframeAnimation.keyPath = "transform.rotation.z" 50 | keyframeAnimation.values = [0, -0.10472, 0.10472, 0] 51 | keyframeAnimation.keyTimes = [0, 0.34, 0.78, 1] 52 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 53 | keyframeAnimation.duration = duration 54 | 55 | return keyframeAnimation 56 | }() 57 | 58 | // Keyframe Animations for path_2 59 | let position_y_path_2: CAKeyframeAnimation = { 60 | let keyframeAnimation = CAKeyframeAnimation() 61 | keyframeAnimation.keyPath = "position.y" 62 | keyframeAnimation.values = [24, 23, 24, 23, 24] 63 | keyframeAnimation.keyTimes = [0, 0.24, 0.48, 0.7, 1] 64 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045), .easeInEaseOut, CAMediaTimingFunction(controlPoints: 0.6, -0.28, 0.735, 0.045), .easeInEaseOut] 65 | keyframeAnimation.duration = duration 66 | 67 | return keyframeAnimation 68 | }() 69 | let transform_rotation_z_path_2: CAKeyframeAnimation = { 70 | let keyframeAnimation = CAKeyframeAnimation() 71 | keyframeAnimation.keyPath = "transform.rotation.z" 72 | keyframeAnimation.values = [0, 0.10472, -0.10472, 0] 73 | keyframeAnimation.keyTimes = [0, 0.34, 0.78, 1] 74 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 75 | keyframeAnimation.duration = duration 76 | 77 | return keyframeAnimation 78 | }() 79 | 80 | // Organize CAKeyframeAnimations by CALayer 81 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 82 | animationsByLayer[view.path_2.layer] = [position_y_path_2, transform_rotation_z_path_2] 83 | animationsByLayer[view.path_1.layer] = [transform_rotation_z_path_1, position_y_path_1] 84 | animationsByLayer[view.path.layer] = [transform_rotation_z_path, position_y_path] 85 | 86 | return animationsByLayer 87 | } 88 | } -------------------------------------------------------------------------------- /Sources/Animations/FlowWheel/FlowWheelActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class FlowWheelActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var flowWheel: FlowWheelView = { 11 | let startView = FlowWheelView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return FlowWheelTimeline(view: flowWheel, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return flowWheel 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/GradientRingActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class GradientRingActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var gradientRing: GradientRingView = { 11 | let startView = GradientRingView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return GradientRingTimeline(view: gradientRing, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return gradientRing 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/GradientRingTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class GradientRingTimeline: Timeline { 9 | public convenience init(view: GradientRingView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = GradientRingTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: GradientRingView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for foregroundCircle 15 | let transform_rotation_z_foregroundCircle: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [-0.785398, -1.5708, 14.1372, 12.5664, 13.3518] 19 | keyframeAnimation.keyTimes = [0, 0.17, 0.55, 0.73, 1] 20 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let strokestart_foregroundCircle: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "strokeStart" 28 | keyframeAnimation.values = [0.75, 0.7, 0, 0] 29 | keyframeAnimation.keyTimes = [0, 0.17, 0.55, 1] 30 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | let strokeend_foregroundCircle: CAKeyframeAnimation = { 36 | let keyframeAnimation = CAKeyframeAnimation() 37 | keyframeAnimation.keyPath = "strokeEnd" 38 | keyframeAnimation.values = [1.001, 1.001, 0.25, 0.25] 39 | keyframeAnimation.keyTimes = [0, 0.32, 0.55, 1] 40 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut] 41 | keyframeAnimation.duration = duration 42 | 43 | return keyframeAnimation 44 | }() 45 | 46 | // Organize CAKeyframeAnimations by CALayer 47 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 48 | animationsByLayer[view.foregroundCircle.layer] = [strokestart_foregroundCircle, transform_rotation_z_foregroundCircle, strokeend_foregroundCircle] 49 | 50 | return animationsByLayer 51 | } 52 | } -------------------------------------------------------------------------------- /Sources/Animations/Griddy/GriddyActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class GriddyActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var griddy: GriddyView = { 11 | let startView = GriddyView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return GriddyTimeline(view: griddy, duration: 1.46, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return griddy 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Gridlock/GridlockActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class GridlockActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var gridlock: GridlockView = { 11 | let startView = GridlockView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return GridlockTimeline(view: gridlock, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return gridlock 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Gridlock/GridlockTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class GridlockTimeline: Timeline { 9 | public convenience init(view: GridlockView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = GridlockTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: GridlockView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for r0 15 | let position_x_r0: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "position.x" 18 | keyframeAnimation.values = [10.5, 10.5, 18.5, 18.5] 19 | keyframeAnimation.keyTimes = [0, 0.5, 0.75, 1] 20 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let position_y_r0: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "position.y" 28 | keyframeAnimation.values = [18.5, 18.5, 10.5, 10.5] 29 | keyframeAnimation.keyTimes = [0, 0.5, 0.75, 1] 30 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | 36 | // Keyframe Animations for r1 37 | let position_x_r1: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "position.x" 40 | keyframeAnimation.values = [18.5, 18.5, 26.5, 26.5] 41 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 1] 42 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | let position_y_r1: CAKeyframeAnimation = { 48 | let keyframeAnimation = CAKeyframeAnimation() 49 | keyframeAnimation.keyPath = "position.y" 50 | keyframeAnimation.values = [10.5, 10.5, 18.5, 18.5] 51 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 1] 52 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut, .easeInEaseOut] 53 | keyframeAnimation.duration = duration 54 | 55 | return keyframeAnimation 56 | }() 57 | 58 | // Keyframe Animations for r2 59 | let position_x_r2: CAKeyframeAnimation = { 60 | let keyframeAnimation = CAKeyframeAnimation() 61 | keyframeAnimation.keyPath = "position.x" 62 | keyframeAnimation.values = [26.5, 18.5, 18.5, 10.5] 63 | keyframeAnimation.keyTimes = [0, 0.25, 0.75, 1] 64 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 65 | keyframeAnimation.duration = duration 66 | 67 | return keyframeAnimation 68 | }() 69 | let position_y_r2: CAKeyframeAnimation = { 70 | let keyframeAnimation = CAKeyframeAnimation() 71 | keyframeAnimation.keyPath = "position.y" 72 | keyframeAnimation.values = [18.5, 26.5, 26.5, 18.5] 73 | keyframeAnimation.keyTimes = [0, 0.25, 0.75, 1] 74 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 75 | keyframeAnimation.duration = duration 76 | 77 | return keyframeAnimation 78 | }() 79 | 80 | // Organize CAKeyframeAnimations by CALayer 81 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 82 | animationsByLayer[view.r2.layer] = [position_x_r2, position_y_r2] 83 | animationsByLayer[view.r0.layer] = [position_x_r0, position_y_r0] 84 | animationsByLayer[view.r1.layer] = [position_x_r1, position_y_r1] 85 | 86 | return animationsByLayer 87 | } 88 | } -------------------------------------------------------------------------------- /Sources/Animations/Gridlock/GridlockView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class GridlockView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var r0: ShapeView! 17 | public var r1: ShapeView! 18 | public var r2: ShapeView! 19 | 20 | public override var intrinsicContentSize: CGSize { 21 | return Defaults.size 22 | } 23 | 24 | public override init(frame: CGRect) { 25 | super.init(frame: frame) 26 | setup() 27 | } 28 | 29 | public required init?(coder: NSCoder) { 30 | super.init(coder: coder) 31 | setup() 32 | } 33 | 34 | private func setup() { 35 | createViews() 36 | addSubviews() 37 | //scale(to: frame.size) 38 | } 39 | 40 | /// Scales `self` and its subviews to `size`. 41 | /// 42 | /// - Parameter size: The size `self` is scaled to. 43 | /// 44 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 45 | /// calculates a view's alignment rectangle based on its untransformed frame." 46 | /// 47 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 48 | /// 49 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 50 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 51 | public func scale(to size: CGSize) { 52 | let x = size.width / Defaults.size.width 53 | let y = size.height / Defaults.size.height 54 | transform = CGAffineTransform(scaleX: x, y: y) 55 | } 56 | 57 | private func createViews() { 58 | CATransaction.suppressAnimations { 59 | createSceneContainer() 60 | createR0() 61 | createR1() 62 | createR2() 63 | } 64 | } 65 | 66 | private func createSceneContainer() { 67 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 68 | sceneContainer.backgroundColor = Defaults.backgroundColor 69 | sceneContainer.layer.cornerRadius = 5.0 70 | sceneContainer.layer.masksToBounds = true 71 | } 72 | 73 | private func createR0() { 74 | r0 = ShapeView(frame: CGRect(x: 10.5, y: 18.5, width: 16, height: 16)) 75 | r0.backgroundColor = UIColor.clear 76 | r0.layer.shadowOffset = CGSize(width: 0, height: 0) 77 | r0.layer.shadowColor = UIColor.clear.cgColor 78 | r0.layer.shadowOpacity = 1 79 | r0.layer.position = CGPoint(x: 10.5, y: 18.5) 80 | r0.layer.bounds = CGRect(x: 0, y: 0, width: 16, height: 16) 81 | r0.layer.masksToBounds = false 82 | r0.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 83 | r0.shapeLayer.strokeColor = UIColor(red: 0.314, green: 0.89, blue: 0.761, alpha: 1).cgColor 84 | r0.shapeLayer.fillColor = nil 85 | r0.shapeLayer.lineDashPattern = [] 86 | r0.shapeLayer.lineDashPhase = 0 87 | r0.shapeLayer.lineWidth = 2 88 | r0.shapeLayer.path = CGPathCreateWithSVGString("M8,0l8,8 -8,8 -8,-8 8,-8zM8,0")! 89 | 90 | } 91 | 92 | private func createR1() { 93 | r1 = ShapeView(frame: CGRect(x: 18.5, y: 10.5, width: 16, height: 16)) 94 | r1.backgroundColor = UIColor.clear 95 | r1.layer.shadowOffset = CGSize(width: 0, height: 0) 96 | r1.layer.shadowColor = UIColor.clear.cgColor 97 | r1.layer.shadowOpacity = 1 98 | r1.layer.position = CGPoint(x: 18.5, y: 10.5) 99 | r1.layer.bounds = CGRect(x: 0, y: 0, width: 16, height: 16) 100 | r1.layer.masksToBounds = false 101 | r1.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 102 | r1.shapeLayer.strokeColor = UIColor(red: 0.314, green: 0.89, blue: 0.761, alpha: 1).cgColor 103 | r1.shapeLayer.fillColor = nil 104 | r1.shapeLayer.lineDashPattern = [] 105 | r1.shapeLayer.lineDashPhase = 0 106 | r1.shapeLayer.lineWidth = 2 107 | r1.shapeLayer.path = CGPathCreateWithSVGString("M8,0l8,8 -8,8 -8,-8 8,-8zM8,0")! 108 | 109 | } 110 | 111 | private func createR2() { 112 | r2 = ShapeView(frame: CGRect(x: 26.5, y: 18.5, width: 16, height: 16)) 113 | r2.backgroundColor = UIColor.clear 114 | r2.layer.shadowOffset = CGSize(width: 0, height: 0) 115 | r2.layer.shadowColor = UIColor.clear.cgColor 116 | r2.layer.shadowOpacity = 1 117 | r2.layer.position = CGPoint(x: 26.5, y: 18.5) 118 | r2.layer.bounds = CGRect(x: 0, y: 0, width: 16, height: 16) 119 | r2.layer.masksToBounds = false 120 | r2.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 121 | r2.shapeLayer.strokeColor = UIColor(red: 0.314, green: 0.89, blue: 0.761, alpha: 1).cgColor 122 | r2.shapeLayer.fillColor = nil 123 | r2.shapeLayer.lineDashPattern = [] 124 | r2.shapeLayer.lineDashPhase = 0 125 | r2.shapeLayer.lineWidth = 2 126 | r2.shapeLayer.path = CGPathCreateWithSVGString("M8,0l8,8 -8,8 -8,-8 8,-8zM8,0")! 127 | 128 | } 129 | 130 | private func addSubviews() { 131 | sceneContainer.addSubview(r0) 132 | sceneContainer.addSubview(r1) 133 | sceneContainer.addSubview(r2) 134 | addSubview(sceneContainer) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Sources/Animations/Hal/HalActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class HalActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var hal: HalView = { 11 | let startView = HalView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.114, green: 0.114, blue: 0.086, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return HalTimeline(view: hal, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return hal 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Hexa/HexaActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class HexaActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var hexa: HexaView = { 11 | let startView = HexaView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return HexaTimeline(view: hexa, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return hexa 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Hexa/HexaView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class HexaView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var hexa0: ShapeView! 17 | public var hexa1: ShapeView! 18 | 19 | public override var intrinsicContentSize: CGSize { 20 | return Defaults.size 21 | } 22 | 23 | public override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | public required init?(coder: NSCoder) { 29 | super.init(coder: coder) 30 | setup() 31 | } 32 | 33 | private func setup() { 34 | createViews() 35 | addSubviews() 36 | //scale(to: frame.size) 37 | } 38 | 39 | /// Scales `self` and its subviews to `size`. 40 | /// 41 | /// - Parameter size: The size `self` is scaled to. 42 | /// 43 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 44 | /// calculates a view's alignment rectangle based on its untransformed frame." 45 | /// 46 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 47 | /// 48 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 49 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 50 | public func scale(to size: CGSize) { 51 | let x = size.width / Defaults.size.width 52 | let y = size.height / Defaults.size.height 53 | transform = CGAffineTransform(scaleX: x, y: y) 54 | } 55 | 56 | private func createViews() { 57 | CATransaction.suppressAnimations { 58 | createSceneContainer() 59 | createHexa0() 60 | createHexa1() 61 | } 62 | } 63 | 64 | private func createSceneContainer() { 65 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 66 | sceneContainer.backgroundColor = Defaults.backgroundColor 67 | sceneContainer.layer.cornerRadius = 5.0 68 | sceneContainer.layer.masksToBounds = true 69 | } 70 | 71 | private func createHexa0() { 72 | hexa0 = ShapeView(frame: CGRect(x: 18.5, y: 18.5, width: 26, height: 30)) 73 | hexa0.backgroundColor = UIColor.clear 74 | hexa0.layer.shadowOffset = CGSize(width: 0, height: 0) 75 | hexa0.layer.shadowColor = UIColor.clear.cgColor 76 | hexa0.layer.shadowOpacity = 1 77 | hexa0.layer.position = CGPoint(x: 18.5, y: 18.5) 78 | hexa0.layer.bounds = CGRect(x: 0, y: 0, width: 26, height: 30) 79 | hexa0.layer.masksToBounds = false 80 | hexa0.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 81 | hexa0.shapeLayer.strokeColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1).cgColor 82 | hexa0.shapeLayer.fillColor = UIColor(red: 0.314, green: 0.89, blue: 0.761, alpha: 1).cgColor 83 | hexa0.shapeLayer.lineDashPattern = [] 84 | hexa0.shapeLayer.lineDashPhase = 0 85 | hexa0.shapeLayer.lineWidth = 4 86 | hexa0.shapeLayer.path = CGPathCreateWithSVGString("M13.005,0l12.995,7.504 -0.01,14.992 -12.986,7.504 -13.005,-7.504 0.01,-14.992 12.995,-7.504zM13.005,0")! 87 | 88 | } 89 | 90 | private func createHexa1() { 91 | hexa1 = ShapeView(frame: CGRect(x: 18.5, y: 18.5, width: 26, height: 30.02)) 92 | hexa1.backgroundColor = UIColor.clear 93 | hexa1.alpha = 0 94 | hexa1.layer.shadowOffset = CGSize(width: 0, height: 0) 95 | hexa1.layer.shadowColor = UIColor.clear.cgColor 96 | hexa1.layer.shadowOpacity = 1 97 | hexa1.layer.position = CGPoint(x: 18.5, y: 18.5) 98 | hexa1.layer.bounds = CGRect(x: 0, y: 0, width: 26, height: 30.02) 99 | hexa1.layer.masksToBounds = false 100 | hexa1.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 101 | hexa1.shapeLayer.strokeColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1).cgColor 102 | hexa1.shapeLayer.fillColor = UIColor(red: 0.314, green: 0.89, blue: 0.761, alpha: 1).cgColor 103 | hexa1.shapeLayer.lineDashPattern = [] 104 | hexa1.shapeLayer.lineDashPhase = 0 105 | hexa1.shapeLayer.lineWidth = 4 106 | hexa1.shapeLayer.path = CGPathCreateWithSVGString("M12.995,30.02l-12.995,-7.509 12.998,-7.505 -0.002,-15.006 13.005,7.509 -12.998,7.505 -0.007,15.006zM12.995,30.02")! 107 | 108 | } 109 | 110 | private func addSubviews() { 111 | sceneContainer.addSubview(hexa0) 112 | sceneContainer.addSubview(hexa1) 113 | addSubview(sceneContainer) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/Animations/Hicks/HicksActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class HicksActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var hicks: HicksView = { 11 | let startView = HicksView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return HicksTimeline(view: hicks, duration: 1.25, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return hicks 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Infinity/InfinityActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class InfinityActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var infinity: InfinityView = { 11 | let startView = InfinityView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return InfinityTimeline(view: infinity, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return infinity 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Infinity/InfinityTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class InfinityTimeline: Timeline { 9 | public convenience init(view: InfinityView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = InfinityTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: InfinityView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for infinity 15 | let strokestart_infinity: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "strokeStart" 18 | keyframeAnimation.values = [0, 0.5] 19 | keyframeAnimation.keyTimes = [0, 1] 20 | keyframeAnimation.timingFunctions = [.linear] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let strokeend_infinity: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "strokeEnd" 28 | keyframeAnimation.values = [0.2, 0.7] 29 | keyframeAnimation.keyTimes = [0, 1] 30 | keyframeAnimation.timingFunctions = [.linear] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | 36 | // Organize CAKeyframeAnimations by CALayer 37 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 38 | animationsByLayer[view.infinity.layer] = [strokeend_infinity, strokestart_infinity] 39 | 40 | return animationsByLayer 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Animations/Magician/MagicianActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class MagicianActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var magician: MagicianView = { 11 | let startView = MagicianView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return MagicianTimeline(view: magician, duration: 2.3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return magician 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Mountains/MountainsActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class MountainsActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var mountains: MountainsView = { 11 | let startView = MountainsView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return MountainsTimeline(view: mountains, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return mountains 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/MoveAlong/MoveAlongActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class MoveAlongActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var moveAlong: MoveAlongView = { 11 | let startView = MoveAlongView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return MoveAlongTimeline(view: moveAlong, duration: 0.66, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return moveAlong 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Nonover/NonoverActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class NonoverActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var nonover: NonoverView = { 11 | let startView = NonoverView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return NonoverTimeline(view: nonover, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return nonover 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Overlapping/OverlappingActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class OverlappingActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var overlapping: OverlappingView = { 11 | let startView = OverlappingView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return OverlappingTimeline(view: overlapping, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return overlapping 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Animations/Penta/PentaActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class PentaActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var penta: PentaView = { 11 | let startView = PentaView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.086, green: 0.086, blue: 0.114, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return PentaTimeline(view: penta, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return penta 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Penta/PentaTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class PentaTimeline: Timeline { 9 | public convenience init(view: PentaView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = PentaTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: PentaView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for pentagon 15 | let strokestart_pentagon: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "strokeStart" 18 | keyframeAnimation.values = [0, 0, 0.83] 19 | keyframeAnimation.keyTimes = [0, 0.05, 1] 20 | keyframeAnimation.timingFunctions = [.linear, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let strokeend_pentagon: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "strokeEnd" 28 | keyframeAnimation.values = [0.16, 0.99] 29 | keyframeAnimation.keyTimes = [0, 1] 30 | keyframeAnimation.timingFunctions = [.easeInEaseOut] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | 36 | // Organize CAKeyframeAnimations by CALayer 37 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 38 | animationsByLayer[view.pentagon.layer] = [strokestart_pentagon, strokeend_pentagon] 39 | 40 | return animationsByLayer 41 | } 42 | } -------------------------------------------------------------------------------- /Sources/Animations/Penta/PentaView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class PentaView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.086, green: 0.086, blue: 0.114, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var pentagon: ShapeView! 17 | 18 | public override var intrinsicContentSize: CGSize { 19 | return Defaults.size 20 | } 21 | 22 | public override init(frame: CGRect) { 23 | super.init(frame: frame) 24 | setup() 25 | } 26 | 27 | public required init?(coder: NSCoder) { 28 | super.init(coder: coder) 29 | setup() 30 | } 31 | 32 | private func setup() { 33 | createViews() 34 | addSubviews() 35 | //scale(to: frame.size) 36 | } 37 | 38 | /// Scales `self` and its subviews to `size`. 39 | /// 40 | /// - Parameter size: The size `self` is scaled to. 41 | /// 42 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 43 | /// calculates a view's alignment rectangle based on its untransformed frame." 44 | /// 45 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 46 | /// 47 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 48 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 49 | public func scale(to size: CGSize) { 50 | let x = size.width / Defaults.size.width 51 | let y = size.height / Defaults.size.height 52 | transform = CGAffineTransform(scaleX: x, y: y) 53 | } 54 | 55 | private func createViews() { 56 | CATransaction.suppressAnimations { 57 | createSceneContainer() 58 | createPentagon() 59 | } 60 | } 61 | 62 | private func createSceneContainer() { 63 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 64 | sceneContainer.backgroundColor = Defaults.backgroundColor 65 | sceneContainer.clipsToBounds = false 66 | } 67 | 68 | private func createPentagon() { 69 | pentagon = ShapeView(frame: CGRect(x: 18.5, y: 18.27, width: 28, height: 26.63)) 70 | pentagon.backgroundColor = UIColor.clear 71 | pentagon.layer.shadowOffset = CGSize(width: 0, height: 0) 72 | pentagon.layer.shadowColor = UIColor.clear.cgColor 73 | pentagon.layer.shadowOpacity = 1 74 | pentagon.layer.position = CGPoint(x: 18.5, y: 18.27) 75 | pentagon.layer.bounds = CGRect(x: 0, y: 0, width: 28, height: 26.63) 76 | pentagon.layer.masksToBounds = false 77 | pentagon.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 78 | pentagon.shapeLayer.strokeColor = UIColor(red: 0.948, green: 0.948, blue: 0.948, alpha: 1).cgColor 79 | pentagon.shapeLayer.fillColor = nil 80 | pentagon.shapeLayer.lineCap = CAShapeLayerLineCap(rawValue: "round") 81 | pentagon.shapeLayer.lineJoin = CAShapeLayerLineJoin(rawValue: "round") 82 | pentagon.shapeLayer.strokeEnd = 0.16 83 | pentagon.shapeLayer.lineDashPattern = [] 84 | pentagon.shapeLayer.lineDashPhase = 0 85 | pentagon.shapeLayer.lineWidth = 4 86 | pentagon.shapeLayer.path = CGPathCreateWithSVGString("M22.653,26.635l-17.305,0 -5.347,-16.458 14,-10.172 14,10.172 -5.347,16.458 -17.305,0 -5.347,-16.458 14,-10.172 14,10.172 -5.347,16.458 -17.305,0 -5.347,-16.458")! 87 | 88 | } 89 | 90 | private func addSubviews() { 91 | sceneContainer.addSubview(pentagon) 92 | addSubview(sceneContainer) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Sources/Animations/Quarbit/QuarbitActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class QuarbitActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var quarbit: QuarbitView = { 11 | let startView = QuarbitView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return QuarbitTimeline(view: quarbit, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return quarbit 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Queued/QueuedActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class QueuedActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var queued: QueuedView = { 11 | let startView = QueuedView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return QueuedTimeline(view: queued, duration: 1.6, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return queued 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Rainbow/RainbowActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class RainbowActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var rainbow: RainbowView = { 11 | let startView = RainbowView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return RainbowTimeline(view: rainbow, duration: 1.77, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return rainbow 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Reflect/ReflectActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class ReflectActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var reflect: ReflectView = { 11 | let startView = ReflectView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return ReflectTimeline(view: reflect, duration: 3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return reflect 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Reflect/ReflectTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class ReflectTimeline: Timeline { 9 | public convenience init(view: ReflectView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = ReflectTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: ReflectView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for blue 15 | let position_y_blue: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "position.y" 18 | keyframeAnimation.values = [26.5, 10.5, 26.5] 19 | keyframeAnimation.keyTimes = [0, 0.5, 1] 20 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for red 27 | let position_y_red: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.y" 30 | keyframeAnimation.values = [10.5, 26.5, 10.5] 31 | keyframeAnimation.keyTimes = [0, 0.5, 1] 32 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | 38 | // Keyframe Animations for maskLayer 39 | let position_y_maskLayer: CAKeyframeAnimation = { 40 | let keyframeAnimation = CAKeyframeAnimation() 41 | keyframeAnimation.keyPath = "position.y" 42 | keyframeAnimation.values = [10.5, 18.5, 26.5, 18.5, 10.5] 43 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 44 | keyframeAnimation.timingFunctions = [.easeIn, .easeOut, .easeIn, .easeOut] 45 | keyframeAnimation.duration = duration 46 | 47 | return keyframeAnimation 48 | }() 49 | 50 | // Keyframe Animations for blueOutline 51 | let position_y_blueOutline: CAKeyframeAnimation = { 52 | let keyframeAnimation = CAKeyframeAnimation() 53 | keyframeAnimation.keyPath = "position.y" 54 | keyframeAnimation.values = [26.5, 10.5, 26.5] 55 | keyframeAnimation.keyTimes = [0, 0.5, 1] 56 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut] 57 | keyframeAnimation.duration = duration 58 | 59 | return keyframeAnimation 60 | }() 61 | 62 | // Keyframe Animations for redOutline 63 | let position_y_redOutline: CAKeyframeAnimation = { 64 | let keyframeAnimation = CAKeyframeAnimation() 65 | keyframeAnimation.keyPath = "position.y" 66 | keyframeAnimation.values = [10.5, 26.5, 10.5] 67 | keyframeAnimation.keyTimes = [0, 0.5, 1] 68 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut] 69 | keyframeAnimation.duration = duration 70 | 71 | return keyframeAnimation 72 | }() 73 | 74 | // Keyframe Animations for colorLayer 75 | let position_y_colorLayer: CAKeyframeAnimation = { 76 | let keyframeAnimation = CAKeyframeAnimation() 77 | keyframeAnimation.keyPath = "position.y" 78 | keyframeAnimation.values = [24, 8, -8, 8, 24] 79 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 80 | keyframeAnimation.timingFunctions = [.easeIn, .easeOut, .easeIn, .easeOut] 81 | keyframeAnimation.duration = duration 82 | 83 | return keyframeAnimation 84 | }() 85 | 86 | // Organize CAKeyframeAnimations by CALayer 87 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 88 | animationsByLayer[view.red.layer] = [position_y_red] 89 | animationsByLayer[view.blue.layer] = [position_y_blue] 90 | animationsByLayer[view.maskLayer.layer] = [position_y_maskLayer] 91 | animationsByLayer[view.blueOutline.layer] = [position_y_blueOutline] 92 | animationsByLayer[view.redOutline.layer] = [position_y_redOutline] 93 | animationsByLayer[view.colorLayer.layer] = [position_y_colorLayer] 94 | 95 | return animationsByLayer 96 | } 97 | } -------------------------------------------------------------------------------- /Sources/Animations/RingItIn/RingItInActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class RingItInActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var ringItIn: RingItInView = { 11 | let startView = RingItInView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return RingItInTimeline(view: ringItIn, duration: 1.5, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return ringItIn 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Ripley/RipleyActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class RipleyActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var ripley: RipleyView = { 11 | let startView = RipleyView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return RipleyTimeline(view: ripley, duration: 0.75, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return ripley 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Roulette/RouletteActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class RouletteActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var roulette: RouletteView = { 11 | let startView = RouletteView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return RouletteTimeline(view: roulette, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return roulette 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/ShiftDrift/ShiftDriftActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class ShiftDriftActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var shiftDrift: ShiftDriftView = { 11 | let startView = ShiftDriftView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return ShiftDriftTimeline(view: shiftDrift, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return shiftDrift 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Shkwv/ShkwvActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class ShkwvActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var shkwv: ShkwvView = { 11 | let startView = ShkwvView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.004, green: 0.086, blue: 0.541, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return ShkwvTimeline(view: shkwv, duration: 1.5, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return shkwv 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/ShowingUp/ShowingUpActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class ShowingUpActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var showingUp: ShowingUpView = { 11 | let startView = ShowingUpView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return ShowingUpTimeline(view: showingUp, duration: 1.5, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return showingUp 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Skeu/SkeuActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class SkeuActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var skeu: SkeuView = { 11 | let startView = SkeuView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return SkeuTimeline(view: skeu, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return skeu 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Skeu/SkeuTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class SkeuTimeline: Timeline { 9 | public convenience init(view: SkeuView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = SkeuTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: SkeuView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for top 15 | let position_y_top: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "position.y" 18 | keyframeAnimation.values = [30.75, 22, 6.25, 14, 30.75] 19 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 20 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for backBar 27 | let strokestart_backBar: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "strokeStart" 30 | keyframeAnimation.values = [1, 0.66, 0, 0.33, 1] 31 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 32 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | 38 | // Keyframe Animations for frontBar 39 | let strokestart_frontBar: CAKeyframeAnimation = { 40 | let keyframeAnimation = CAKeyframeAnimation() 41 | keyframeAnimation.keyPath = "strokeStart" 42 | keyframeAnimation.values = [1, 0.66, 0, 0.33, 1] 43 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 44 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 45 | keyframeAnimation.duration = duration 46 | 47 | return keyframeAnimation 48 | }() 49 | 50 | // Keyframe Animations for leftBar 51 | let strokestart_leftBar: CAKeyframeAnimation = { 52 | let keyframeAnimation = CAKeyframeAnimation() 53 | keyframeAnimation.keyPath = "strokeStart" 54 | keyframeAnimation.values = [1, 0.66, 0, 0.33, 1] 55 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 56 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 57 | keyframeAnimation.duration = duration 58 | 59 | return keyframeAnimation 60 | }() 61 | 62 | // Keyframe Animations for rightBar 63 | let strokestart_rightBar: CAKeyframeAnimation = { 64 | let keyframeAnimation = CAKeyframeAnimation() 65 | keyframeAnimation.keyPath = "strokeStart" 66 | keyframeAnimation.values = [1, 0.66, 0, 0.33, 1] 67 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 68 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 69 | keyframeAnimation.duration = duration 70 | 71 | return keyframeAnimation 72 | }() 73 | 74 | // Keyframe Animations for colorLayer 75 | let position_y_colorLayer: CAKeyframeAnimation = { 76 | let keyframeAnimation = CAKeyframeAnimation() 77 | keyframeAnimation.keyPath = "position.y" 78 | keyframeAnimation.values = [39, 31, 15.07, 23, 39] 79 | keyframeAnimation.keyTimes = [0, 0.25, 0.5, 0.75, 1] 80 | keyframeAnimation.timingFunctions = [.easeInEaseOut, .easeInEaseOut, .easeInEaseOut, .easeInEaseOut] 81 | keyframeAnimation.duration = duration 82 | 83 | return keyframeAnimation 84 | }() 85 | 86 | // Organize CAKeyframeAnimations by CALayer 87 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 88 | animationsByLayer[view.backBar.layer] = [strokestart_backBar] 89 | animationsByLayer[view.leftBar.layer] = [strokestart_leftBar] 90 | animationsByLayer[view.frontBar.layer] = [strokestart_frontBar] 91 | animationsByLayer[view.rightBar.layer] = [strokestart_rightBar] 92 | animationsByLayer[view.top.layer] = [position_y_top] 93 | animationsByLayer[view.colorLayer.layer] = [position_y_colorLayer] 94 | 95 | return animationsByLayer 96 | } 97 | } -------------------------------------------------------------------------------- /Sources/Animations/SpinUp/SpinUpActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class SpinUpActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var spinUp: SpinUpView = { 11 | let startView = SpinUpView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.22, green: 0.282, blue: 0.353, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return SpinUpTimeline(view: spinUp, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return spinUp 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/SpinUp/SpinUpTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class SpinUpTimeline: Timeline { 9 | public convenience init(view: SpinUpView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = SpinUpTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: SpinUpView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for group 15 | let transform_rotation_z_group: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, 2.54818] 19 | keyframeAnimation.keyTimes = [0, 1] 20 | keyframeAnimation.timingFunctions = [.easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for loaderCircle0 27 | let strokestart_loaderCircle0: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "strokeStart" 30 | keyframeAnimation.values = [0, 0, 0.26, 0.26] 31 | keyframeAnimation.keyTimes = [0, 0.5, 0.83, 1] 32 | keyframeAnimation.timingFunctions = [.linear, .easeIn, .easeInEaseOut] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | let strokeend_loaderCircle0: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "strokeEnd" 40 | keyframeAnimation.values = [0.02, 0.28, 0.28] 41 | keyframeAnimation.keyTimes = [0, 0.33, 1] 42 | keyframeAnimation.timingFunctions = [.easeIn, .easeInEaseOut] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | 48 | // Keyframe Animations for loaderCircle1 49 | let strokestart_loaderCircle1: CAKeyframeAnimation = { 50 | let keyframeAnimation = CAKeyframeAnimation() 51 | keyframeAnimation.keyPath = "strokeStart" 52 | keyframeAnimation.values = [0, 0, 0.26, 0.26] 53 | keyframeAnimation.keyTimes = [0, 0.5, 0.83, 1] 54 | keyframeAnimation.timingFunctions = [.linear, .easeIn, .easeInEaseOut] 55 | keyframeAnimation.duration = duration 56 | 57 | return keyframeAnimation 58 | }() 59 | let strokeend_loaderCircle1: CAKeyframeAnimation = { 60 | let keyframeAnimation = CAKeyframeAnimation() 61 | keyframeAnimation.keyPath = "strokeEnd" 62 | keyframeAnimation.values = [0.02, 0.28, 0.28] 63 | keyframeAnimation.keyTimes = [0, 0.33, 1] 64 | keyframeAnimation.timingFunctions = [.easeIn, .easeInEaseOut] 65 | keyframeAnimation.duration = duration 66 | 67 | return keyframeAnimation 68 | }() 69 | 70 | // Keyframe Animations for loaderCircle2 71 | let strokestart_loaderCircle2: CAKeyframeAnimation = { 72 | let keyframeAnimation = CAKeyframeAnimation() 73 | keyframeAnimation.keyPath = "strokeStart" 74 | keyframeAnimation.values = [0, 0, 0.26, 0.26] 75 | keyframeAnimation.keyTimes = [0, 0.5, 0.83, 1] 76 | keyframeAnimation.timingFunctions = [.linear, .easeIn, .easeInEaseOut] 77 | keyframeAnimation.duration = duration 78 | 79 | return keyframeAnimation 80 | }() 81 | let strokeend_loaderCircle2: CAKeyframeAnimation = { 82 | let keyframeAnimation = CAKeyframeAnimation() 83 | keyframeAnimation.keyPath = "strokeEnd" 84 | keyframeAnimation.values = [0.02, 0.28, 0.28] 85 | keyframeAnimation.keyTimes = [0, 0.33, 1] 86 | keyframeAnimation.timingFunctions = [.easeIn, .easeInEaseOut] 87 | keyframeAnimation.duration = duration 88 | 89 | return keyframeAnimation 90 | }() 91 | 92 | // Organize CAKeyframeAnimations by CALayer 93 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 94 | animationsByLayer[view.group.layer] = [transform_rotation_z_group] 95 | animationsByLayer[view.loaderCircle0.layer] = [strokestart_loaderCircle0, strokeend_loaderCircle0] 96 | animationsByLayer[view.loaderCircle2.layer] = [strokestart_loaderCircle2, strokeend_loaderCircle2] 97 | animationsByLayer[view.loaderCircle1.layer] = [strokestart_loaderCircle1, strokeend_loaderCircle1] 98 | 99 | return animationsByLayer 100 | } 101 | } -------------------------------------------------------------------------------- /Sources/Animations/Spindle/SpindleActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class SpindleActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var spindle: SpindleView = { 11 | let startView = SpindleView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.455, green: 0.282, blue: 0.988, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return SpindleTimeline(view: spindle, duration: 1.75, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return spindle 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Spinning/SpinningActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class SpinningActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var spinning: SpinningView = { 11 | let startView = SpinningView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return SpinningTimeline(view: spinning, duration: 4, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return spinning 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Splayed/SplayedActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class SplayedActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var splayed: SplayedView = { 11 | let startView = SplayedView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return SplayedTimeline(view: splayed, duration: 1.5, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return splayed 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/SquareUp/SquareUpActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class SquareUpActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var squareUp: SquareUpView = { 11 | let startView = SquareUpView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return SquareUpTimeline(view: squareUp, duration: 3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return squareUp 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/StandBy/StandByActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class StandByActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var standBy: StandByView = { 11 | let startView = StandByView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 0.114, green: 0.114, blue: 0.086, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return StandByTimeline(view: standBy, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return standBy 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/StandBy/StandByView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class StandByView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 37, height: 37) 12 | public static let backgroundColor = UIColor(red: 0.114, green: 0.114, blue: 0.086, alpha: 1) 13 | } 14 | 15 | public var sceneContainer: UIView! 16 | public var ovalIn: ShapeView! 17 | public var ovalOut: ShapeView! 18 | 19 | public override var intrinsicContentSize: CGSize { 20 | return Defaults.size 21 | } 22 | 23 | public override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | public required init?(coder: NSCoder) { 29 | super.init(coder: coder) 30 | setup() 31 | } 32 | 33 | private func setup() { 34 | createViews() 35 | addSubviews() 36 | //scale(to: frame.size) 37 | } 38 | 39 | /// Scales `self` and its subviews to `size`. 40 | /// 41 | /// - Parameter size: The size `self` is scaled to. 42 | /// 43 | /// UIKit specifies: "In iOS 8.0 and later, the transform property does not affect Auto Layout. Auto layout 44 | /// calculates a view's alignment rectangle based on its untransformed frame." 45 | /// 46 | /// see: https://developer.apple.com/documentation/uikit/uiview/1622459-transform 47 | /// 48 | /// If there are any constraints in IB affecting the frame of `self`, this method will have consequences on 49 | /// layout / rendering. To properly scale an animation, you will have to position the view manually. 50 | public func scale(to size: CGSize) { 51 | let x = size.width / Defaults.size.width 52 | let y = size.height / Defaults.size.height 53 | transform = CGAffineTransform(scaleX: x, y: y) 54 | } 55 | 56 | private func createViews() { 57 | CATransaction.suppressAnimations { 58 | createSceneContainer() 59 | createOvalIn() 60 | createOvalOut() 61 | } 62 | } 63 | 64 | private func createSceneContainer() { 65 | sceneContainer = UIView(frame: CGRect(origin: CGPoint(), size: Defaults.size)) 66 | sceneContainer.backgroundColor = Defaults.backgroundColor 67 | sceneContainer.layer.cornerRadius = 5.0 68 | sceneContainer.layer.masksToBounds = true 69 | } 70 | 71 | private func createOvalIn() { 72 | ovalIn = ShapeView(frame: CGRect(x: 18.5, y: 18.5, width: 28, height: 28)) 73 | ovalIn.backgroundColor = UIColor.clear 74 | ovalIn.layer.shadowOffset = CGSize(width: 0, height: 0) 75 | ovalIn.layer.shadowRadius = 4 76 | ovalIn.layer.shadowColor = UIColor(red: 1, green: 0.992, blue: 0.976, alpha: 1).cgColor 77 | ovalIn.layer.shadowOpacity = 1 78 | ovalIn.layer.position = CGPoint(x: 18.5, y: 18.5) 79 | ovalIn.layer.bounds = CGRect(x: 0, y: 0, width: 28, height: 28) 80 | ovalIn.layer.masksToBounds = false 81 | ovalIn.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 82 | ovalIn.shapeLayer.fillColor = UIColor(red: 1, green: 0.992, blue: 0.976, alpha: 1).cgColor 83 | ovalIn.shapeLayer.lineDashPattern = [] 84 | ovalIn.shapeLayer.lineDashPhase = 0 85 | ovalIn.shapeLayer.lineWidth = 0 86 | ovalIn.shapeLayer.path = CGPathCreateWithSVGString("M14,0c-7.732,0,-14,6.268,-14,14 0,7.732,6.268,14,14,14 7.732,0,14,-6.268,14,-14 0,-7.732,-6.268,-14,-14,-14zM14,3.027c6.06,0,10.973,4.913,10.973,10.973 0,6.06,-4.913,10.973,-10.973,10.973 -6.06,0,-10.973,-4.913,-10.973,-10.973 0,-6.06,4.913,-10.973,10.973,-10.973zM14,3.027")! 87 | 88 | } 89 | 90 | private func createOvalOut() { 91 | ovalOut = ShapeView(frame: CGRect(x: 18.5, y: 18.5, width: 21.95, height: 21.95)) 92 | ovalOut.backgroundColor = UIColor.clear 93 | ovalOut.alpha = 0 94 | ovalOut.layer.shadowOffset = CGSize(width: 0, height: 0) 95 | ovalOut.layer.shadowRadius = 0 96 | ovalOut.layer.shadowColor = UIColor(red: 1, green: 0.992, blue: 0.976, alpha: 0).cgColor 97 | ovalOut.layer.shadowOpacity = 1 98 | ovalOut.layer.position = CGPoint(x: 18.5, y: 18.5) 99 | ovalOut.layer.bounds = CGRect(x: 0, y: 0, width: 21.95, height: 21.95) 100 | ovalOut.layer.masksToBounds = false 101 | ovalOut.shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd 102 | ovalOut.shapeLayer.fillColor = UIColor(red: 1, green: 0.992, blue: 0.976, alpha: 1).cgColor 103 | ovalOut.shapeLayer.lineDashPattern = [] 104 | ovalOut.shapeLayer.lineDashPhase = 0 105 | ovalOut.shapeLayer.lineWidth = 0 106 | ovalOut.shapeLayer.path = CGPathCreateWithSVGString("M10.975,0c-6.063,0,-10.975,4.912,-10.975,10.975 0,6.063,4.912,10.975,10.975,10.975 6.063,0,10.975,-4.912,10.975,-10.975 0,-6.063,-4.914,-10.975,-10.975,-10.975zM10.975,0.103c6.063,0,10.872,4.809,10.872,10.872 0,6.063,-4.809,10.873,-10.872,10.873 -6.063,0,-10.859,-4.824,-10.859,-10.887 0,-6.063,4.797,-10.857,10.859,-10.857zM10.975,0.103")! 107 | 108 | } 109 | 110 | private func addSubviews() { 111 | sceneContainer.addSubview(ovalIn) 112 | sceneContainer.addSubview(ovalOut) 113 | addSubview(sceneContainer) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Sources/Animations/StretchAround/StretchAroundActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class StretchAroundActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var stretchAround: StretchAroundView = { 11 | let startView = StretchAroundView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return StretchAroundTimeline(view: stretchAround, duration: 2, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return stretchAround 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Triplex/TriplexActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class TriplexActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var triplex: TriplexView = { 11 | let startView = TriplexView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return TriplexTimeline(view: triplex, duration: 1, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return triplex 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Triplex/TriplexTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class TriplexTimeline: Timeline { 9 | public convenience init(view: TriplexView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = TriplexTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: TriplexView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for dot0 15 | let transform_rotation_z_dot0: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "transform.rotation.z" 18 | keyframeAnimation.values = [0, 6.28319] 19 | keyframeAnimation.keyTimes = [0, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | let anchorpoint_y_dot0: CAKeyframeAnimation = { 26 | let keyframeAnimation = CAKeyframeAnimation() 27 | keyframeAnimation.keyPath = "anchorPoint.y" 28 | keyframeAnimation.values = [1.25, 0.5, 1.25] 29 | keyframeAnimation.keyTimes = [0, 0.5, 1] 30 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.55, 0.055, 0.675, 0.19), CAMediaTimingFunction(controlPoints: 0.215, 0.61, 0.355, 1)] 31 | keyframeAnimation.duration = duration 32 | 33 | return keyframeAnimation 34 | }() 35 | 36 | // Keyframe Animations for dot1 37 | let transform_rotation_z_dot1: CAKeyframeAnimation = { 38 | let keyframeAnimation = CAKeyframeAnimation() 39 | keyframeAnimation.keyPath = "transform.rotation.z" 40 | keyframeAnimation.values = [2.0944, 8.37758] 41 | keyframeAnimation.keyTimes = [0, 1] 42 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 43 | keyframeAnimation.duration = duration 44 | 45 | return keyframeAnimation 46 | }() 47 | let anchorpoint_y_dot1: CAKeyframeAnimation = { 48 | let keyframeAnimation = CAKeyframeAnimation() 49 | keyframeAnimation.keyPath = "anchorPoint.y" 50 | keyframeAnimation.values = [1.25, 0.5, 1.25] 51 | keyframeAnimation.keyTimes = [0, 0.5, 1] 52 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.55, 0.055, 0.675, 0.19), CAMediaTimingFunction(controlPoints: 0.215, 0.61, 0.355, 1)] 53 | keyframeAnimation.duration = duration 54 | 55 | return keyframeAnimation 56 | }() 57 | 58 | // Keyframe Animations for dot2 59 | let transform_rotation_z_dot2: CAKeyframeAnimation = { 60 | let keyframeAnimation = CAKeyframeAnimation() 61 | keyframeAnimation.keyPath = "transform.rotation.z" 62 | keyframeAnimation.values = [4.18879, 10.472] 63 | keyframeAnimation.keyTimes = [0, 1] 64 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)] 65 | keyframeAnimation.duration = duration 66 | 67 | return keyframeAnimation 68 | }() 69 | let anchorpoint_y_dot2: CAKeyframeAnimation = { 70 | let keyframeAnimation = CAKeyframeAnimation() 71 | keyframeAnimation.keyPath = "anchorPoint.y" 72 | keyframeAnimation.values = [1.25, 0.5, 1.25] 73 | keyframeAnimation.keyTimes = [0, 0.5, 1] 74 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.55, 0.055, 0.675, 0.19), CAMediaTimingFunction(controlPoints: 0.215, 0.61, 0.355, 1)] 75 | keyframeAnimation.duration = duration 76 | 77 | return keyframeAnimation 78 | }() 79 | 80 | // Organize CAKeyframeAnimations by CALayer 81 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 82 | animationsByLayer[view.dot1.layer] = [transform_rotation_z_dot1, anchorpoint_y_dot1] 83 | animationsByLayer[view.dot2.layer] = [anchorpoint_y_dot2, transform_rotation_z_dot2] 84 | animationsByLayer[view.dot0.layer] = [anchorpoint_y_dot0, transform_rotation_z_dot0] 85 | 86 | return animationsByLayer 87 | } 88 | } -------------------------------------------------------------------------------- /Sources/Animations/Tumble/TumbleActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class TumbleActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var tumble: TumbleView = { 11 | let startView = TumbleView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return TumbleTimeline(view: tumble, duration: 3, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return tumble 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Xact/XactActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | class XactActivityIndicatorView: ActivityIndicatorView { 10 | private lazy var xact: XactView = { 11 | let startView = XactView(frame: .zero) 12 | startView.scale(to: frame.size) 13 | //The background color for this custom activity indicator should always be solid 14 | //Otherwise, the native ActivityIndicatorView animation will be visible 15 | startView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) 16 | return startView 17 | }() 18 | 19 | override var timeline: Timeline? { 20 | return XactTimeline(view: xact, duration: 2.4, repeatCount: .greatestFiniteMagnitude) 21 | } 22 | 23 | override func createView() -> UIView { 24 | return xact 25 | } 26 | } -------------------------------------------------------------------------------- /Sources/Animations/Xact/XactTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class XactTimeline: Timeline { 9 | public convenience init(view: XactView, duration: TimeInterval, autoreverses: Bool = false, repeatCount: Float = 0) { 10 | let animationsByLayer = XactTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration, autoreverses: autoreverses, repeatCount: repeatCount) 12 | } 13 | private static func animationsByLayer(view: XactView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 14 | // Keyframe Animations for r1 15 | let position_y_r1: CAKeyframeAnimation = { 16 | let keyframeAnimation = CAKeyframeAnimation() 17 | keyframeAnimation.keyPath = "position.y" 18 | keyframeAnimation.values = [0, -18.5, -18.5] 19 | keyframeAnimation.keyTimes = [0, 0.0833333, 1] 20 | keyframeAnimation.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .easeInEaseOut] 21 | keyframeAnimation.duration = duration 22 | 23 | return keyframeAnimation 24 | }() 25 | 26 | // Keyframe Animations for r2 27 | let position_y_r2: CAKeyframeAnimation = { 28 | let keyframeAnimation = CAKeyframeAnimation() 29 | keyframeAnimation.keyPath = "position.y" 30 | keyframeAnimation.values = [18.5, 18.5, 0, 0, 0, -18.5, -18.5] 31 | keyframeAnimation.keyTimes = [0, 0.0833333, 0.166667, 0.245833, 0.25, 0.333333, 1] 32 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear, .linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .easeInEaseOut] 33 | keyframeAnimation.duration = duration 34 | 35 | return keyframeAnimation 36 | }() 37 | 38 | // Keyframe Animations for r3 39 | let position_y_r3: CAKeyframeAnimation = { 40 | let keyframeAnimation = CAKeyframeAnimation() 41 | keyframeAnimation.keyPath = "position.y" 42 | keyframeAnimation.values = [37, 37, 18.5, 18.5, 18.5, 0, 0, 0, -18.5, -18.5] 43 | keyframeAnimation.keyTimes = [0, 0.166667, 0.25, 0.329167, 0.333333, 0.416667, 0.495833, 0.5, 0.583333, 1] 44 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear, .linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear, .linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .easeInEaseOut] 45 | keyframeAnimation.duration = duration 46 | 47 | return keyframeAnimation 48 | }() 49 | 50 | // Keyframe Animations for r4 51 | let position_y_r4: CAKeyframeAnimation = { 52 | let keyframeAnimation = CAKeyframeAnimation() 53 | keyframeAnimation.keyPath = "position.y" 54 | keyframeAnimation.values = [37, 37, 18.5, 18.5, 18.5, 0, 0, 0, -18.5, -18.5] 55 | keyframeAnimation.keyTimes = [0, 0.416667, 0.5, 0.579167, 0.583333, 0.666667, 0.745833, 0.75, 0.833333, 1] 56 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear, .linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear, .linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .easeInEaseOut] 57 | keyframeAnimation.duration = duration 58 | 59 | return keyframeAnimation 60 | }() 61 | 62 | // Keyframe Animations for r5 63 | let position_y_r5: CAKeyframeAnimation = { 64 | let keyframeAnimation = CAKeyframeAnimation() 65 | keyframeAnimation.keyPath = "position.y" 66 | keyframeAnimation.values = [37, 37, 18.5, 18.5, 18.5, 0, 0] 67 | keyframeAnimation.keyTimes = [0, 0.666667, 0.75, 0.829167, 0.833333, 0.916667, 1] 68 | keyframeAnimation.timingFunctions = [.linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear, .linear, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1), .linear] 69 | keyframeAnimation.duration = duration 70 | 71 | return keyframeAnimation 72 | }() 73 | 74 | // Keyframe Animations for r6 75 | let position_y_r6: CAKeyframeAnimation = { 76 | let keyframeAnimation = CAKeyframeAnimation() 77 | keyframeAnimation.keyPath = "position.y" 78 | keyframeAnimation.values = [37, 37, 18.5] 79 | keyframeAnimation.keyTimes = [0, 0.916667, 1] 80 | keyframeAnimation.timingFunctions = [.easeInEaseOut, CAMediaTimingFunction(controlPoints: 0.23, 1, 0.32, 1)] 81 | keyframeAnimation.duration = duration 82 | 83 | return keyframeAnimation 84 | }() 85 | 86 | // Organize CAKeyframeAnimations by CALayer 87 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 88 | animationsByLayer[view.r3.layer] = [position_y_r3] 89 | animationsByLayer[view.r4.layer] = [position_y_r4] 90 | animationsByLayer[view.r2.layer] = [position_y_r2] 91 | animationsByLayer[view.r6.layer] = [position_y_r6] 92 | animationsByLayer[view.r1.layer] = [position_y_r1] 93 | animationsByLayer[view.r5.layer] = [position_y_r5] 94 | 95 | return animationsByLayer 96 | } 97 | } -------------------------------------------------------------------------------- /Sources/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // Made with Flow. 2 | 3 | import UIKit 4 | 5 | @UIApplicationMain 6 | class AppDelegate: UIResponder, UIApplicationDelegate { 7 | var window: UIWindow? 8 | } 9 | -------------------------------------------------------------------------------- /Sources/FlowCommon/CAKeyframeAnimation+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import Foundation 21 | import UIKit 22 | 23 | public extension CAKeyframeAnimation { 24 | var reversed: CAKeyframeAnimation { 25 | let reversed = CAKeyframeAnimation(keyPath: keyPath) 26 | reversed.keyTimes = keyTimes?.reversed().map { NSNumber(floatLiteral: 1.0 - $0.doubleValue) } 27 | reversed.values = values?.reversed() 28 | reversed.timingFunctions = timingFunctions?.reversed().map { $0.reversed } 29 | reversed.duration = duration 30 | return reversed 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/FlowCommon/CAMediaTimingFunction+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import Foundation 21 | import UIKit 22 | 23 | public extension CAMediaTimingFunction { 24 | static let linear = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) 25 | static let easeIn = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn) 26 | static let easeOut = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) 27 | static let easeInEaseOut = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) 28 | 29 | var reversed: CAMediaTimingFunction { 30 | let (c1, c2) = controlPoints 31 | let x1 = Float(1 - c2.x) 32 | let y1 = Float(1 - c2.y) 33 | let x2 = Float(1 - c1.x) 34 | let y2 = Float(1 - c1.y) 35 | return CAMediaTimingFunction(controlPoints: x1, y1, x2, y2) 36 | } 37 | 38 | var controlPoints: (CGPoint, CGPoint) { 39 | var c1: [Float] = [0, 0] 40 | var c2: [Float] = [0, 0] 41 | getControlPoint(at: 1, values: &c1) 42 | getControlPoint(at: 2, values: &c2) 43 | 44 | let c1x = CGFloat(c1[0]) 45 | let c1y = CGFloat(c1[1]) 46 | let c2x = CGFloat(c2[0]) 47 | let c2y = CGFloat(c2[1]) 48 | 49 | return (CGPoint(x: c1x, y: c1y), CGPoint(x: c2x, y: c2y)) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Sources/FlowCommon/CATransaction+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | extension CATransaction { 23 | static public func suppressAnimations(actions: () -> Void) { 24 | begin() 25 | setAnimationDuration(0) 26 | actions() 27 | commit() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/FlowCommon/NSMutableParagraphStyle+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | extension NSMutableParagraphStyle { 23 | convenience init(alignment: NSTextAlignment, 24 | firstLineHeadIndent: CGFloat, 25 | headIndent: CGFloat, 26 | tailIndent: CGFloat, 27 | lineHeightMultiple: CGFloat, 28 | maximumLineHeight: CGFloat, 29 | minimumLineHeight: CGFloat, 30 | lineSpacing: CGFloat, 31 | paragraphSpacing: CGFloat, 32 | paragraphSpacingBefore: CGFloat) { 33 | self.init() 34 | self.alignment = alignment 35 | self.firstLineHeadIndent = firstLineHeadIndent 36 | self.headIndent = headIndent 37 | self.tailIndent = tailIndent 38 | self.lineHeightMultiple = lineHeightMultiple 39 | self.maximumLineHeight = maximumLineHeight 40 | self.minimumLineHeight = minimumLineHeight 41 | self.lineSpacing = lineSpacing 42 | self.paragraphSpacing = paragraphSpacing 43 | self.paragraphSpacingBefore = paragraphSpacingBefore 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Sources/FlowCommon/NSShadow+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | extension NSShadow { 23 | convenience init(blurRadius: CGFloat, offset: CGSize, color: UIColor) { 24 | self.init() 25 | shadowBlurRadius = blurRadius 26 | shadowOffset = offset 27 | shadowColor = color 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/FlowCommon/ShapeView.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | open class ShapeView: UIView { 23 | open var shapeLayer: CAShapeLayer { 24 | return layer as! CAShapeLayer 25 | } 26 | 27 | /// A sublayer which can be used to apply a gradient fill to `self`. 28 | open var gradientLayer: CAGradientLayer? { 29 | set { 30 | // Remove old gradient layer 31 | if let gradientLayer = gradientLayer { 32 | gradientLayer.removeFromSuperlayer() 33 | } 34 | // Replace old gradient with new one 35 | if let newGradientLayer = newValue { 36 | layer.addSublayer(newGradientLayer) 37 | } 38 | } 39 | 40 | get { 41 | return layer.sublayers?.first(where: { $0 is CAGradientLayer }) as? CAGradientLayer 42 | } 43 | } 44 | 45 | public func addGradient(type: CAGradientLayerType, startPoint: CGPoint, endPoint: CGPoint, stops: [(color: CGColor, location: NSNumber)]) { 46 | let gradientLayer = CAGradientLayer() 47 | gradientLayer.frame = shapeLayer.bounds 48 | self.gradientLayer = gradientLayer 49 | 50 | 51 | let mask = CAShapeLayer() 52 | mask.path = shapeLayer.path 53 | mask.fillColor = UIColor.black.cgColor 54 | mask.strokeColor = nil 55 | 56 | gradientLayer.startPoint = startPoint 57 | gradientLayer.endPoint = endPoint 58 | gradientLayer.colors = stops.map { $0.color } 59 | gradientLayer.locations = stops.map { $0.location } 60 | gradientLayer.type = type 61 | gradientLayer.frame = shapeLayer.bounds 62 | gradientLayer.mask = mask 63 | } 64 | 65 | open var path: CGPath? { 66 | get { 67 | return shapeLayer.path 68 | } 69 | set { 70 | shapeLayer.path = newValue 71 | } 72 | } 73 | 74 | override open class var layerClass: AnyClass { 75 | return CAShapeLayer.self 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Sources/FlowCommon/Sound.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import AVFoundation 21 | 22 | public final class Sound { 23 | 24 | static func playAudio(_ audio: AVAudioPlayer, delay: TimeInterval) { 25 | audio.prepareToPlay() 26 | let time = DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) 27 | DispatchQueue.main.asyncAfter(deadline: time) { 28 | audio.play() 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/FlowCommon/TextView.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | open class TextView: UILabel { 23 | open var textLayer: CATextLayer { 24 | return layer as! CATextLayer 25 | } 26 | 27 | override open class var layerClass: AnyClass { 28 | return CATextLayer.self 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/FlowCommon/UIImage+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | extension UIImage { 23 | func resized(to size: CGSize) -> UIImage { 24 | let rect = CGRect(origin: .zero, size: size) 25 | let vertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height) 26 | return UIGraphicsImageRenderer(size: size).image { _ in 27 | let ctx = UIGraphicsGetCurrentContext() 28 | ctx?.saveGState() 29 | ctx?.concatenate(vertical) 30 | draw(in: rect) 31 | ctx?.restoreGState() 32 | UIGraphicsEndImageContext() 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/FlowCommon/UIView+Extension.swift: -------------------------------------------------------------------------------- 1 | // Copyright © 2016-2019 JABT Labs Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to 5 | // deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 | // sell copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: The above copyright 9 | // notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | // IN THE SOFTWARE. 19 | 20 | import UIKit 21 | 22 | extension UIView { 23 | func setTransform(scaleX: CGFloat, scaleY: CGFloat, rotationAngle: CGFloat) { 24 | var transform = CGAffineTransform.identity 25 | transform = transform.concatenating(CGAffineTransform(scaleX: scaleX, y: 1.0)) 26 | transform = transform.concatenating(CGAffineTransform(scaleX: 1.0, y: scaleY)) 27 | transform = transform.concatenating(CGAffineTransform(rotationAngle: rotationAngle)) 28 | self.transform = transform 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/LaunchAnimation/LaunchAnimationTimeline.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class LaunchAnimationTimeline: Timeline { 9 | public convenience init(view: LaunchAnimationView, duration: TimeInterval) { 10 | let animationsByLayer = LaunchAnimationTimeline.animationsByLayer(view: view, duration: duration) 11 | self.init(view: view, animationsByLayer: animationsByLayer, sounds: [], duration: duration) 12 | } 13 | 14 | private static func animationsByLayer(view: LaunchAnimationView, duration: TimeInterval) -> [CALayer: [CAKeyframeAnimation]] { 15 | // Keyframe Animations for wblue 16 | let opacity_wblue: CAKeyframeAnimation = { 17 | let keyframeAnimation = CAKeyframeAnimation() 18 | keyframeAnimation.keyPath = "opacity" 19 | keyframeAnimation.values = [1, 0] 20 | keyframeAnimation.keyTimes = [0.7, 1] 21 | keyframeAnimation.timingFunctions = [.easeOut] 22 | keyframeAnimation.duration = 1 23 | 24 | return keyframeAnimation 25 | }() 26 | 27 | // Keyframe Animations for wred 28 | let opacity_wred: CAKeyframeAnimation = { 29 | let keyframeAnimation = CAKeyframeAnimation() 30 | keyframeAnimation.keyPath = "opacity" 31 | keyframeAnimation.values = [1, 0] 32 | keyframeAnimation.keyTimes = [0.56, 0.86] 33 | keyframeAnimation.timingFunctions = [.easeOut] 34 | keyframeAnimation.duration = 1 35 | 36 | return keyframeAnimation 37 | }() 38 | 39 | // Keyframe Animations for wpink 40 | let opacity_wpink: CAKeyframeAnimation = { 41 | let keyframeAnimation = CAKeyframeAnimation() 42 | keyframeAnimation.keyPath = "opacity" 43 | keyframeAnimation.values = [1, 0] 44 | keyframeAnimation.keyTimes = [0.42, 0.72] 45 | keyframeAnimation.timingFunctions = [.easeOut] 46 | keyframeAnimation.duration = 1 47 | 48 | return keyframeAnimation 49 | }() 50 | 51 | // Keyframe Animations for o 52 | let opacity_o: CAKeyframeAnimation = { 53 | let keyframeAnimation = CAKeyframeAnimation() 54 | keyframeAnimation.keyPath = "opacity" 55 | keyframeAnimation.values = [1, 0] 56 | keyframeAnimation.keyTimes = [0.28, 0.58] 57 | keyframeAnimation.timingFunctions = [.easeOut] 58 | keyframeAnimation.duration = 1 59 | 60 | return keyframeAnimation 61 | }() 62 | 63 | // Keyframe Animations for l 64 | let opacity_l: CAKeyframeAnimation = { 65 | let keyframeAnimation = CAKeyframeAnimation() 66 | keyframeAnimation.keyPath = "opacity" 67 | keyframeAnimation.values = [1, 0] 68 | keyframeAnimation.keyTimes = [0.14, 0.44] 69 | keyframeAnimation.timingFunctions = [.easeOut] 70 | keyframeAnimation.duration = 1 71 | 72 | return keyframeAnimation 73 | }() 74 | 75 | // Keyframe Animations for f 76 | let opacity_f: CAKeyframeAnimation = { 77 | let keyframeAnimation = CAKeyframeAnimation() 78 | keyframeAnimation.keyPath = "opacity" 79 | keyframeAnimation.values = [1, 0] 80 | keyframeAnimation.keyTimes = [0, 0.3] 81 | keyframeAnimation.timingFunctions = [.easeOut] 82 | keyframeAnimation.duration = 1 83 | 84 | return keyframeAnimation 85 | }() 86 | 87 | // Organize CAKeyframeAnimations by CALayer 88 | var animationsByLayer = [CALayer: [CAKeyframeAnimation]]() 89 | animationsByLayer[view.l.layer] = [opacity_l] 90 | animationsByLayer[view.o.layer] = [opacity_o] 91 | animationsByLayer[view.wblue.layer] = [opacity_wblue] 92 | animationsByLayer[view.f.layer] = [opacity_f] 93 | animationsByLayer[view.wpink.layer] = [opacity_wpink] 94 | animationsByLayer[view.wred.layer] = [opacity_wred] 95 | 96 | return animationsByLayer 97 | } 98 | } -------------------------------------------------------------------------------- /Sources/LaunchAnimation/LaunchAnimationView.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | @IBDesignable 9 | public class LaunchAnimationView: UIView { 10 | public struct Defaults { 11 | public static let size = CGSize(width: 290, height: 60) 12 | public static let backgroundColor = UIColor.white 13 | } 14 | 15 | public var wblue: ShapeView! 16 | public var wred: ShapeView! 17 | public var wpink: ShapeView! 18 | public var o: ShapeView! 19 | public var l: ShapeView! 20 | public var f: ShapeView! 21 | 22 | public override var intrinsicContentSize: CGSize { 23 | return Defaults.size 24 | } 25 | 26 | public override init(frame: CGRect) { 27 | super.init(frame: frame) 28 | createViews() 29 | addSubviews() 30 | } 31 | 32 | public required init?(coder: NSCoder) { 33 | super.init(coder: coder) 34 | backgroundColor = Defaults.backgroundColor 35 | createViews() 36 | addSubviews() 37 | } 38 | 39 | private func createViews() { 40 | CATransaction.suppressAnimations { 41 | createWblue() 42 | createWred() 43 | createWpink() 44 | createO() 45 | createL() 46 | createF() 47 | } 48 | } 49 | 50 | private func createWblue() { 51 | wblue = ShapeView(frame: CGRect(x: 262, y: 30, width: 56, height: 56)) 52 | wblue.backgroundColor = .clear 53 | wblue.layer.position = CGPoint(x: 262, y: 30) 54 | wblue.layer.bounds = CGRect(x: 0, y: 0, width: 56, height: 56) 55 | wblue.shapeLayer.fillRule = .evenOdd 56 | wblue.shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 1, alpha: 1).cgColor 57 | wblue.shapeLayer.path = CGPathCreateWithSVGString("M0,52.901l0,-49.808c0,-1.709,1.384,-3.093,3.093,-3.093l49.808,0c2.756,0,4.135,3.331,2.187,5.279l-49.808,49.809c-1.949,1.948,-5.28,0.568,-5.28,-2.187") 58 | 59 | } 60 | 61 | private func createWred() { 62 | wred = ShapeView(frame: CGRect(x: 230, y: 30, width: 56, height: 56)) 63 | wred.backgroundColor = .clear 64 | wred.layer.position = CGPoint(x: 230, y: 30) 65 | wred.layer.bounds = CGRect(x: 0, y: 0, width: 56, height: 56) 66 | wred.shapeLayer.fillRule = .evenOdd 67 | wred.shapeLayer.fillColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1).cgColor 68 | wred.shapeLayer.path = CGPathCreateWithSVGString("M0,52.901l0,-49.808c0,-1.709,1.384,-3.093,3.093,-3.093l49.808,0c2.756,0,4.135,3.331,2.187,5.279l-49.808,49.809c-1.949,1.948,-5.28,0.568,-5.28,-2.187") 69 | 70 | } 71 | 72 | private func createWpink() { 73 | wpink = ShapeView(frame: CGRect(x: 246, y: 16, width: 24, height: 28)) 74 | wpink.backgroundColor = .clear 75 | wpink.layer.position = CGPoint(x: 246, y: 16) 76 | wpink.layer.bounds = CGRect(x: 0, y: 0, width: 24, height: 28) 77 | wpink.shapeLayer.fillRule = .evenOdd 78 | wpink.shapeLayer.fillColor = UIColor(red: 0.988, green: 0.176, blue: 0.988, alpha: 1).cgColor 79 | wpink.shapeLayer.path = CGPathCreateWithSVGString("M0,28l0,-24.947c0,-1.687,1.384,-3.053,3.093,-3.053l17.808,0c2.756,0,4.135,3.288,2.187,5.211zM0,28") 80 | 81 | } 82 | 83 | private func createO() { 84 | o = ShapeView(frame: CGRect(x: 158, y: 30, width: 60, height: 60)) 85 | o.backgroundColor = .clear 86 | o.layer.position = CGPoint(x: 158, y: 30) 87 | o.layer.bounds = CGRect(x: 0, y: 0, width: 60, height: 60) 88 | o.shapeLayer.fillRule = .evenOdd 89 | o.shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 1, alpha: 1).cgColor 90 | o.shapeLayer.path = CGPathCreateWithSVGString("M30,60l0,0c-16.568,0,-30,-13.432,-30,-30.001l0,0c0,-16.569,13.432,-29.999,30,-29.999l0,0c16.568,0,30,13.431,30,29.999l0,0c0,16.569,-13.432,30.001,-30,30.001") 91 | 92 | } 93 | 94 | private func createL() { 95 | l = ShapeView(frame: CGRect(x: 94, y: 30, width: 56, height: 56)) 96 | l.backgroundColor = .clear 97 | l.layer.position = CGPoint(x: 94, y: 30) 98 | l.layer.bounds = CGRect(x: 0, y: 0, width: 56, height: 56) 99 | l.shapeLayer.fillRule = .evenOdd 100 | l.shapeLayer.fillColor = UIColor(red: 0.992, green: 0.004, blue: 0.471, alpha: 1).cgColor 101 | l.shapeLayer.path = CGPathCreateWithSVGString("M52.901,56l-49.808,0c-1.709,0,-3.093,-1.384,-3.093,-3.093l0,-49.808c0,-2.756,3.331,-4.135,5.279,-2.187l49.809,49.808c1.948,1.949,0.568,5.28,-2.187,5.28") 102 | 103 | } 104 | 105 | private func createF() { 106 | f = ShapeView(frame: CGRect(x: 28, y: 30, width: 56, height: 56)) 107 | f.backgroundColor = .clear 108 | f.layer.position = CGPoint(x: 28, y: 30) 109 | f.layer.bounds = CGRect(x: 0, y: 0, width: 56, height: 56) 110 | f.shapeLayer.fillRule = .evenOdd 111 | f.shapeLayer.fillColor = UIColor(red: 0, green: 0, blue: 1, alpha: 1).cgColor 112 | f.shapeLayer.path = CGPathCreateWithSVGString("M0,52.901l0,-49.808c0,-1.709,1.384,-3.093,3.093,-3.093l49.808,0c2.756,0,4.135,3.331,2.187,5.279l-49.808,49.809c-1.949,1.948,-5.28,0.568,-5.28,-2.187") 113 | 114 | } 115 | 116 | private func addSubviews() { 117 | addSubview(wblue) 118 | addSubview(wred) 119 | addSubview(wpink) 120 | addSubview(o) 121 | addSubview(l) 122 | addSubview(f) 123 | } 124 | } -------------------------------------------------------------------------------- /Sources/LaunchAnimation/LaunchAnimationViewController.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class LaunchAnimationViewController: UIViewController { 9 | @IBOutlet public weak var scene: LaunchAnimationView! 10 | public var timeline: LaunchAnimationTimeline! 11 | 12 | public override func viewDidLoad() { 13 | super.viewDidLoad() 14 | scene.clipsToBounds = true 15 | timeline = LaunchAnimationTimeline(view: scene, duration: 1) 16 | 17 | timeline.play() 18 | DispatchQueue.main.asyncAfter(deadline: .now() + timeline.duration) { 19 | self.showSceneViewController() 20 | } 21 | } 22 | 23 | func showSceneViewController() { 24 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 25 | let sceneViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") 26 | sceneViewController.modalPresentationStyle = .custom 27 | sceneViewController.modalTransitionStyle = .crossDissolve 28 | present(sceneViewController, animated: true, completion: nil) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/ViewController.swift: -------------------------------------------------------------------------------- 1 | // Made With Flow. 2 | // 3 | // DO NOT MODIFY, your changes will be lost when this file is regenerated. 4 | // 5 | 6 | import UIKit 7 | 8 | public class ViewController: UIViewController { 9 | override public func viewDidLoad() { 10 | super.viewDidLoad() 11 | self.modalPresentationCapturesStatusBarAppearance = true 12 | } 13 | 14 | public override var prefersStatusBarHidden: Bool { 15 | return true 16 | } 17 | } 18 | --------------------------------------------------------------------------------