├── .DS_Store ├── BabyPigAnimation ├── .DS_Store ├── BabyPigAnimation.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── gaojun.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── gaojun.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── BabyPigAnimation │ ├── .DS_Store │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Like-Blue.imageset │ │ │ ├── Contents.json │ │ │ └── Like-Blue@2x.png │ │ ├── Like.imageset │ │ │ ├── Contents.json │ │ │ └── Like@2x.png │ │ ├── Sparkle.imageset │ │ │ ├── Contents.json │ │ │ └── Sparkle.png │ │ ├── chooser-button-input-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-button-input-highlighted@2x.png │ │ ├── chooser-button-input.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-button-input@2x.png │ │ ├── chooser-button-tab-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-button-tab-highlighted@2x.png │ │ ├── chooser-button-tab.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-button-tab@2x.png │ │ ├── chooser-moment-button-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-button-highlighted@2x.png │ │ ├── chooser-moment-button.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-button@2x.png │ │ ├── chooser-moment-icon-camera-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-camera-highlighted@2x.png │ │ ├── chooser-moment-icon-camera.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-camera@2x.png │ │ ├── chooser-moment-icon-music-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-music-highlighted@2x.png │ │ ├── chooser-moment-icon-music.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-music@2x.png │ │ ├── chooser-moment-icon-place-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-place-highlighted@2x.png │ │ ├── chooser-moment-icon-place.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-place@2x.png │ │ ├── chooser-moment-icon-sleep-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-sleep-highlighted@2x.png │ │ ├── chooser-moment-icon-sleep.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-sleep@2x.png │ │ ├── chooser-moment-icon-thought-highlighted.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-thought-highlighted@2x.png │ │ └── chooser-moment-icon-thought.imageset │ │ │ ├── Contents.json │ │ │ └── chooser-moment-icon-thought@2x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── DCPathButton │ │ ├── DCPathButton.h │ │ ├── DCPathButton.m │ │ ├── DCPathCenterButton.h │ │ ├── DCPathCenterButton.m │ │ ├── DCPathItemButton.h │ │ └── DCPathItemButton.m │ ├── DWBubbleMenuButton │ │ ├── DWBubbleMenuButton.h │ │ └── DWBubbleMenuButton.m │ ├── GJAnimationViewControllers │ │ ├── BaseAnimationViewController.h │ │ ├── BaseAnimationViewController.m │ │ ├── BaseViewController.h │ │ ├── BaseViewController.m │ │ ├── CombinationAniViewController.h │ │ ├── CombinationAniViewController.m │ │ ├── GroupAnimationViewController.h │ │ ├── GroupAnimationViewController.m │ │ ├── KeyFrameAnimationViewController.h │ │ ├── KeyFrameAnimationViewController.m │ │ ├── TransitionAnimationViewController.h │ │ └── TransitionAnimationViewController.m │ ├── Info.plist │ ├── MCFireworksButton │ │ ├── MCFireworksButton.h │ │ ├── MCFireworksButton.m │ │ ├── MCFireworksView.h │ │ └── MCFireworksView.m │ ├── ProgressView │ │ ├── GJProgressAniView.h │ │ └── GJProgressAniView.m │ ├── Sounds │ │ ├── bloom.caf │ │ ├── fold.caf │ │ └── selected.caf │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── BabyPigAnimationTests │ ├── BabyPigAnimationTests.m │ └── Info.plist └── BabyPigAnimationUITests │ ├── BabyPigAnimationUITests.m │ └── Info.plist └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/.DS_Store -------------------------------------------------------------------------------- /BabyPigAnimation/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/.DS_Store -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E1B8448F2069EC3A007D4F1B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B8448E2069EC3A007D4F1B /* AppDelegate.m */; }; 11 | E1B844922069EC3A007D4F1B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844912069EC3A007D4F1B /* ViewController.m */; }; 12 | E1B844952069EC3A007D4F1B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E1B844932069EC3A007D4F1B /* Main.storyboard */; }; 13 | E1B844972069EC3A007D4F1B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E1B844962069EC3A007D4F1B /* Assets.xcassets */; }; 14 | E1B8449A2069EC3A007D4F1B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E1B844982069EC3A007D4F1B /* LaunchScreen.storyboard */; }; 15 | E1B8449D2069EC3A007D4F1B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B8449C2069EC3A007D4F1B /* main.m */; }; 16 | E1B844A72069EC3A007D4F1B /* BabyPigAnimationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844A62069EC3A007D4F1B /* BabyPigAnimationTests.m */; }; 17 | E1B844B22069EC3A007D4F1B /* BabyPigAnimationUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844B12069EC3A007D4F1B /* BabyPigAnimationUITests.m */; }; 18 | E1B844C22069FF64007D4F1B /* BaseAnimationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844C12069FF64007D4F1B /* BaseAnimationViewController.m */; }; 19 | E1B844C5206A04ED007D4F1B /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844C4206A04ED007D4F1B /* BaseViewController.m */; }; 20 | E1B844C8206A0DCC007D4F1B /* KeyFrameAnimationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844C7206A0DCC007D4F1B /* KeyFrameAnimationViewController.m */; }; 21 | E1B844CB206A230B007D4F1B /* GroupAnimationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844CA206A230B007D4F1B /* GroupAnimationViewController.m */; }; 22 | E1B844CE206A2B45007D4F1B /* TransitionAnimationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844CD206A2B45007D4F1B /* TransitionAnimationViewController.m */; }; 23 | E1B844DE206A34A6007D4F1B /* DCPathButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844D1206A34A6007D4F1B /* DCPathButton.m */; }; 24 | E1B844DF206A34A6007D4F1B /* DCPathCenterButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844D3206A34A6007D4F1B /* DCPathCenterButton.m */; }; 25 | E1B844E0206A34A6007D4F1B /* DCPathItemButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844D5206A34A6007D4F1B /* DCPathItemButton.m */; }; 26 | E1B844E1206A34A6007D4F1B /* DWBubbleMenuButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844D8206A34A6007D4F1B /* DWBubbleMenuButton.m */; }; 27 | E1B844E2206A34A6007D4F1B /* MCFireworksButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844DB206A34A6007D4F1B /* MCFireworksButton.m */; }; 28 | E1B844E3206A34A6007D4F1B /* MCFireworksView.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844DD206A34A6007D4F1B /* MCFireworksView.m */; }; 29 | E1B844E9206A3711007D4F1B /* CombinationAniViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1B844E8206A3711007D4F1B /* CombinationAniViewController.m */; }; 30 | E1B844EE206A3AB9007D4F1B /* bloom.caf in Resources */ = {isa = PBXBuildFile; fileRef = E1B844EB206A3AB9007D4F1B /* bloom.caf */; }; 31 | E1B844EF206A3AB9007D4F1B /* fold.caf in Resources */ = {isa = PBXBuildFile; fileRef = E1B844EC206A3AB9007D4F1B /* fold.caf */; }; 32 | E1B844F0206A3AB9007D4F1B /* selected.caf in Resources */ = {isa = PBXBuildFile; fileRef = E1B844ED206A3AB9007D4F1B /* selected.caf */; }; 33 | E1FDCEA32071F46D006B0CB1 /* GJProgressAniView.m in Sources */ = {isa = PBXBuildFile; fileRef = E1FDCEA22071F46D006B0CB1 /* GJProgressAniView.m */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | E1B844A32069EC3A007D4F1B /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = E1B844822069EC3A007D4F1B /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = E1B844892069EC3A007D4F1B; 42 | remoteInfo = BabyPigAnimation; 43 | }; 44 | E1B844AE2069EC3A007D4F1B /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = E1B844822069EC3A007D4F1B /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = E1B844892069EC3A007D4F1B; 49 | remoteInfo = BabyPigAnimation; 50 | }; 51 | /* End PBXContainerItemProxy section */ 52 | 53 | /* Begin PBXFileReference section */ 54 | E1B8448A2069EC3A007D4F1B /* BabyPigAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BabyPigAnimation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | E1B8448D2069EC3A007D4F1B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 56 | E1B8448E2069EC3A007D4F1B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 57 | E1B844902069EC3A007D4F1B /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 58 | E1B844912069EC3A007D4F1B /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 59 | E1B844942069EC3A007D4F1B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 60 | E1B844962069EC3A007D4F1B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 61 | E1B844992069EC3A007D4F1B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 62 | E1B8449B2069EC3A007D4F1B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | E1B8449C2069EC3A007D4F1B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 64 | E1B844A22069EC3A007D4F1B /* BabyPigAnimationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BabyPigAnimationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | E1B844A62069EC3A007D4F1B /* BabyPigAnimationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BabyPigAnimationTests.m; sourceTree = ""; }; 66 | E1B844A82069EC3A007D4F1B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | E1B844AD2069EC3A007D4F1B /* BabyPigAnimationUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BabyPigAnimationUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | E1B844B12069EC3A007D4F1B /* BabyPigAnimationUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BabyPigAnimationUITests.m; sourceTree = ""; }; 69 | E1B844B32069EC3A007D4F1B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 70 | E1B844C02069FF64007D4F1B /* BaseAnimationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseAnimationViewController.h; sourceTree = ""; }; 71 | E1B844C12069FF64007D4F1B /* BaseAnimationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseAnimationViewController.m; sourceTree = ""; }; 72 | E1B844C3206A04ED007D4F1B /* BaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = ""; }; 73 | E1B844C4206A04ED007D4F1B /* BaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseViewController.m; sourceTree = ""; }; 74 | E1B844C6206A0DCC007D4F1B /* KeyFrameAnimationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyFrameAnimationViewController.h; sourceTree = ""; }; 75 | E1B844C7206A0DCC007D4F1B /* KeyFrameAnimationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeyFrameAnimationViewController.m; sourceTree = ""; }; 76 | E1B844C9206A230B007D4F1B /* GroupAnimationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupAnimationViewController.h; sourceTree = ""; }; 77 | E1B844CA206A230B007D4F1B /* GroupAnimationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupAnimationViewController.m; sourceTree = ""; }; 78 | E1B844CC206A2B45007D4F1B /* TransitionAnimationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TransitionAnimationViewController.h; sourceTree = ""; }; 79 | E1B844CD206A2B45007D4F1B /* TransitionAnimationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TransitionAnimationViewController.m; sourceTree = ""; }; 80 | E1B844D0206A34A6007D4F1B /* DCPathButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCPathButton.h; sourceTree = ""; }; 81 | E1B844D1206A34A6007D4F1B /* DCPathButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCPathButton.m; sourceTree = ""; }; 82 | E1B844D2206A34A6007D4F1B /* DCPathCenterButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCPathCenterButton.h; sourceTree = ""; }; 83 | E1B844D3206A34A6007D4F1B /* DCPathCenterButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCPathCenterButton.m; sourceTree = ""; }; 84 | E1B844D4206A34A6007D4F1B /* DCPathItemButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DCPathItemButton.h; sourceTree = ""; }; 85 | E1B844D5206A34A6007D4F1B /* DCPathItemButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DCPathItemButton.m; sourceTree = ""; }; 86 | E1B844D7206A34A6007D4F1B /* DWBubbleMenuButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWBubbleMenuButton.h; sourceTree = ""; }; 87 | E1B844D8206A34A6007D4F1B /* DWBubbleMenuButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DWBubbleMenuButton.m; sourceTree = ""; }; 88 | E1B844DA206A34A6007D4F1B /* MCFireworksButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCFireworksButton.h; sourceTree = ""; }; 89 | E1B844DB206A34A6007D4F1B /* MCFireworksButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCFireworksButton.m; sourceTree = ""; }; 90 | E1B844DC206A34A6007D4F1B /* MCFireworksView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCFireworksView.h; sourceTree = ""; }; 91 | E1B844DD206A34A6007D4F1B /* MCFireworksView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCFireworksView.m; sourceTree = ""; }; 92 | E1B844E7206A3711007D4F1B /* CombinationAniViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CombinationAniViewController.h; sourceTree = ""; }; 93 | E1B844E8206A3711007D4F1B /* CombinationAniViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CombinationAniViewController.m; sourceTree = ""; }; 94 | E1B844EB206A3AB9007D4F1B /* bloom.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = bloom.caf; sourceTree = ""; }; 95 | E1B844EC206A3AB9007D4F1B /* fold.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = fold.caf; sourceTree = ""; }; 96 | E1B844ED206A3AB9007D4F1B /* selected.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = selected.caf; sourceTree = ""; }; 97 | E1FDCEA12071F46D006B0CB1 /* GJProgressAniView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GJProgressAniView.h; sourceTree = ""; }; 98 | E1FDCEA22071F46D006B0CB1 /* GJProgressAniView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GJProgressAniView.m; sourceTree = ""; }; 99 | /* End PBXFileReference section */ 100 | 101 | /* Begin PBXFrameworksBuildPhase section */ 102 | E1B844872069EC3A007D4F1B /* Frameworks */ = { 103 | isa = PBXFrameworksBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | E1B8449F2069EC3A007D4F1B /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | E1B844AA2069EC3A007D4F1B /* Frameworks */ = { 117 | isa = PBXFrameworksBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | /* End PBXFrameworksBuildPhase section */ 124 | 125 | /* Begin PBXGroup section */ 126 | E1B844812069EC3A007D4F1B = { 127 | isa = PBXGroup; 128 | children = ( 129 | E1B8448C2069EC3A007D4F1B /* BabyPigAnimation */, 130 | E1B844A52069EC3A007D4F1B /* BabyPigAnimationTests */, 131 | E1B844B02069EC3A007D4F1B /* BabyPigAnimationUITests */, 132 | E1B8448B2069EC3A007D4F1B /* Products */, 133 | ); 134 | sourceTree = ""; 135 | }; 136 | E1B8448B2069EC3A007D4F1B /* Products */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | E1B8448A2069EC3A007D4F1B /* BabyPigAnimation.app */, 140 | E1B844A22069EC3A007D4F1B /* BabyPigAnimationTests.xctest */, 141 | E1B844AD2069EC3A007D4F1B /* BabyPigAnimationUITests.xctest */, 142 | ); 143 | name = Products; 144 | sourceTree = ""; 145 | }; 146 | E1B8448C2069EC3A007D4F1B /* BabyPigAnimation */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | E1FDCEA02071F41D006B0CB1 /* ProgressView */, 150 | E1B844EA206A3AB9007D4F1B /* Sounds */, 151 | E1B844CF206A34A6007D4F1B /* DCPathButton */, 152 | E1B844D6206A34A6007D4F1B /* DWBubbleMenuButton */, 153 | E1B844D9206A34A6007D4F1B /* MCFireworksButton */, 154 | E1B844BF2069FF41007D4F1B /* GJAnimationViewControllers */, 155 | E1B8448D2069EC3A007D4F1B /* AppDelegate.h */, 156 | E1B8448E2069EC3A007D4F1B /* AppDelegate.m */, 157 | E1B844902069EC3A007D4F1B /* ViewController.h */, 158 | E1B844912069EC3A007D4F1B /* ViewController.m */, 159 | E1B844932069EC3A007D4F1B /* Main.storyboard */, 160 | E1B844962069EC3A007D4F1B /* Assets.xcassets */, 161 | E1B844982069EC3A007D4F1B /* LaunchScreen.storyboard */, 162 | E1B8449B2069EC3A007D4F1B /* Info.plist */, 163 | E1B8449C2069EC3A007D4F1B /* main.m */, 164 | ); 165 | path = BabyPigAnimation; 166 | sourceTree = ""; 167 | }; 168 | E1B844A52069EC3A007D4F1B /* BabyPigAnimationTests */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | E1B844A62069EC3A007D4F1B /* BabyPigAnimationTests.m */, 172 | E1B844A82069EC3A007D4F1B /* Info.plist */, 173 | ); 174 | path = BabyPigAnimationTests; 175 | sourceTree = ""; 176 | }; 177 | E1B844B02069EC3A007D4F1B /* BabyPigAnimationUITests */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | E1B844B12069EC3A007D4F1B /* BabyPigAnimationUITests.m */, 181 | E1B844B32069EC3A007D4F1B /* Info.plist */, 182 | ); 183 | path = BabyPigAnimationUITests; 184 | sourceTree = ""; 185 | }; 186 | E1B844BF2069FF41007D4F1B /* GJAnimationViewControllers */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | E1B844C3206A04ED007D4F1B /* BaseViewController.h */, 190 | E1B844C4206A04ED007D4F1B /* BaseViewController.m */, 191 | E1B844C02069FF64007D4F1B /* BaseAnimationViewController.h */, 192 | E1B844C12069FF64007D4F1B /* BaseAnimationViewController.m */, 193 | E1B844C6206A0DCC007D4F1B /* KeyFrameAnimationViewController.h */, 194 | E1B844C7206A0DCC007D4F1B /* KeyFrameAnimationViewController.m */, 195 | E1B844C9206A230B007D4F1B /* GroupAnimationViewController.h */, 196 | E1B844CA206A230B007D4F1B /* GroupAnimationViewController.m */, 197 | E1B844CC206A2B45007D4F1B /* TransitionAnimationViewController.h */, 198 | E1B844CD206A2B45007D4F1B /* TransitionAnimationViewController.m */, 199 | E1B844E7206A3711007D4F1B /* CombinationAniViewController.h */, 200 | E1B844E8206A3711007D4F1B /* CombinationAniViewController.m */, 201 | ); 202 | path = GJAnimationViewControllers; 203 | sourceTree = ""; 204 | }; 205 | E1B844CF206A34A6007D4F1B /* DCPathButton */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | E1B844D0206A34A6007D4F1B /* DCPathButton.h */, 209 | E1B844D1206A34A6007D4F1B /* DCPathButton.m */, 210 | E1B844D2206A34A6007D4F1B /* DCPathCenterButton.h */, 211 | E1B844D3206A34A6007D4F1B /* DCPathCenterButton.m */, 212 | E1B844D4206A34A6007D4F1B /* DCPathItemButton.h */, 213 | E1B844D5206A34A6007D4F1B /* DCPathItemButton.m */, 214 | ); 215 | path = DCPathButton; 216 | sourceTree = ""; 217 | }; 218 | E1B844D6206A34A6007D4F1B /* DWBubbleMenuButton */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | E1B844D7206A34A6007D4F1B /* DWBubbleMenuButton.h */, 222 | E1B844D8206A34A6007D4F1B /* DWBubbleMenuButton.m */, 223 | ); 224 | path = DWBubbleMenuButton; 225 | sourceTree = ""; 226 | }; 227 | E1B844D9206A34A6007D4F1B /* MCFireworksButton */ = { 228 | isa = PBXGroup; 229 | children = ( 230 | E1B844DA206A34A6007D4F1B /* MCFireworksButton.h */, 231 | E1B844DB206A34A6007D4F1B /* MCFireworksButton.m */, 232 | E1B844DC206A34A6007D4F1B /* MCFireworksView.h */, 233 | E1B844DD206A34A6007D4F1B /* MCFireworksView.m */, 234 | ); 235 | path = MCFireworksButton; 236 | sourceTree = ""; 237 | }; 238 | E1B844EA206A3AB9007D4F1B /* Sounds */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | E1B844EB206A3AB9007D4F1B /* bloom.caf */, 242 | E1B844EC206A3AB9007D4F1B /* fold.caf */, 243 | E1B844ED206A3AB9007D4F1B /* selected.caf */, 244 | ); 245 | path = Sounds; 246 | sourceTree = ""; 247 | }; 248 | E1FDCEA02071F41D006B0CB1 /* ProgressView */ = { 249 | isa = PBXGroup; 250 | children = ( 251 | E1FDCEA12071F46D006B0CB1 /* GJProgressAniView.h */, 252 | E1FDCEA22071F46D006B0CB1 /* GJProgressAniView.m */, 253 | ); 254 | path = ProgressView; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXGroup section */ 258 | 259 | /* Begin PBXNativeTarget section */ 260 | E1B844892069EC3A007D4F1B /* BabyPigAnimation */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = E1B844B62069EC3A007D4F1B /* Build configuration list for PBXNativeTarget "BabyPigAnimation" */; 263 | buildPhases = ( 264 | E1B844862069EC3A007D4F1B /* Sources */, 265 | E1B844872069EC3A007D4F1B /* Frameworks */, 266 | E1B844882069EC3A007D4F1B /* Resources */, 267 | ); 268 | buildRules = ( 269 | ); 270 | dependencies = ( 271 | ); 272 | name = BabyPigAnimation; 273 | productName = BabyPigAnimation; 274 | productReference = E1B8448A2069EC3A007D4F1B /* BabyPigAnimation.app */; 275 | productType = "com.apple.product-type.application"; 276 | }; 277 | E1B844A12069EC3A007D4F1B /* BabyPigAnimationTests */ = { 278 | isa = PBXNativeTarget; 279 | buildConfigurationList = E1B844B92069EC3A007D4F1B /* Build configuration list for PBXNativeTarget "BabyPigAnimationTests" */; 280 | buildPhases = ( 281 | E1B8449E2069EC3A007D4F1B /* Sources */, 282 | E1B8449F2069EC3A007D4F1B /* Frameworks */, 283 | E1B844A02069EC3A007D4F1B /* Resources */, 284 | ); 285 | buildRules = ( 286 | ); 287 | dependencies = ( 288 | E1B844A42069EC3A007D4F1B /* PBXTargetDependency */, 289 | ); 290 | name = BabyPigAnimationTests; 291 | productName = BabyPigAnimationTests; 292 | productReference = E1B844A22069EC3A007D4F1B /* BabyPigAnimationTests.xctest */; 293 | productType = "com.apple.product-type.bundle.unit-test"; 294 | }; 295 | E1B844AC2069EC3A007D4F1B /* BabyPigAnimationUITests */ = { 296 | isa = PBXNativeTarget; 297 | buildConfigurationList = E1B844BC2069EC3A007D4F1B /* Build configuration list for PBXNativeTarget "BabyPigAnimationUITests" */; 298 | buildPhases = ( 299 | E1B844A92069EC3A007D4F1B /* Sources */, 300 | E1B844AA2069EC3A007D4F1B /* Frameworks */, 301 | E1B844AB2069EC3A007D4F1B /* Resources */, 302 | ); 303 | buildRules = ( 304 | ); 305 | dependencies = ( 306 | E1B844AF2069EC3A007D4F1B /* PBXTargetDependency */, 307 | ); 308 | name = BabyPigAnimationUITests; 309 | productName = BabyPigAnimationUITests; 310 | productReference = E1B844AD2069EC3A007D4F1B /* BabyPigAnimationUITests.xctest */; 311 | productType = "com.apple.product-type.bundle.ui-testing"; 312 | }; 313 | /* End PBXNativeTarget section */ 314 | 315 | /* Begin PBXProject section */ 316 | E1B844822069EC3A007D4F1B /* Project object */ = { 317 | isa = PBXProject; 318 | attributes = { 319 | LastUpgradeCheck = 0920; 320 | ORGANIZATIONNAME = "Jun Gao"; 321 | TargetAttributes = { 322 | E1B844892069EC3A007D4F1B = { 323 | CreatedOnToolsVersion = 9.2; 324 | ProvisioningStyle = Automatic; 325 | }; 326 | E1B844A12069EC3A007D4F1B = { 327 | CreatedOnToolsVersion = 9.2; 328 | ProvisioningStyle = Automatic; 329 | TestTargetID = E1B844892069EC3A007D4F1B; 330 | }; 331 | E1B844AC2069EC3A007D4F1B = { 332 | CreatedOnToolsVersion = 9.2; 333 | ProvisioningStyle = Automatic; 334 | TestTargetID = E1B844892069EC3A007D4F1B; 335 | }; 336 | }; 337 | }; 338 | buildConfigurationList = E1B844852069EC3A007D4F1B /* Build configuration list for PBXProject "BabyPigAnimation" */; 339 | compatibilityVersion = "Xcode 8.0"; 340 | developmentRegion = en; 341 | hasScannedForEncodings = 0; 342 | knownRegions = ( 343 | en, 344 | Base, 345 | ); 346 | mainGroup = E1B844812069EC3A007D4F1B; 347 | productRefGroup = E1B8448B2069EC3A007D4F1B /* Products */; 348 | projectDirPath = ""; 349 | projectRoot = ""; 350 | targets = ( 351 | E1B844892069EC3A007D4F1B /* BabyPigAnimation */, 352 | E1B844A12069EC3A007D4F1B /* BabyPigAnimationTests */, 353 | E1B844AC2069EC3A007D4F1B /* BabyPigAnimationUITests */, 354 | ); 355 | }; 356 | /* End PBXProject section */ 357 | 358 | /* Begin PBXResourcesBuildPhase section */ 359 | E1B844882069EC3A007D4F1B /* Resources */ = { 360 | isa = PBXResourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | E1B8449A2069EC3A007D4F1B /* LaunchScreen.storyboard in Resources */, 364 | E1B844F0206A3AB9007D4F1B /* selected.caf in Resources */, 365 | E1B844972069EC3A007D4F1B /* Assets.xcassets in Resources */, 366 | E1B844EE206A3AB9007D4F1B /* bloom.caf in Resources */, 367 | E1B844EF206A3AB9007D4F1B /* fold.caf in Resources */, 368 | E1B844952069EC3A007D4F1B /* Main.storyboard in Resources */, 369 | ); 370 | runOnlyForDeploymentPostprocessing = 0; 371 | }; 372 | E1B844A02069EC3A007D4F1B /* Resources */ = { 373 | isa = PBXResourcesBuildPhase; 374 | buildActionMask = 2147483647; 375 | files = ( 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | }; 379 | E1B844AB2069EC3A007D4F1B /* Resources */ = { 380 | isa = PBXResourcesBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | }; 386 | /* End PBXResourcesBuildPhase section */ 387 | 388 | /* Begin PBXSourcesBuildPhase section */ 389 | E1B844862069EC3A007D4F1B /* Sources */ = { 390 | isa = PBXSourcesBuildPhase; 391 | buildActionMask = 2147483647; 392 | files = ( 393 | E1B844E0206A34A6007D4F1B /* DCPathItemButton.m in Sources */, 394 | E1B844DE206A34A6007D4F1B /* DCPathButton.m in Sources */, 395 | E1B844CE206A2B45007D4F1B /* TransitionAnimationViewController.m in Sources */, 396 | E1B844E9206A3711007D4F1B /* CombinationAniViewController.m in Sources */, 397 | E1B844E3206A34A6007D4F1B /* MCFireworksView.m in Sources */, 398 | E1B844DF206A34A6007D4F1B /* DCPathCenterButton.m in Sources */, 399 | E1B844922069EC3A007D4F1B /* ViewController.m in Sources */, 400 | E1FDCEA32071F46D006B0CB1 /* GJProgressAniView.m in Sources */, 401 | E1B844CB206A230B007D4F1B /* GroupAnimationViewController.m in Sources */, 402 | E1B844C5206A04ED007D4F1B /* BaseViewController.m in Sources */, 403 | E1B844E1206A34A6007D4F1B /* DWBubbleMenuButton.m in Sources */, 404 | E1B8449D2069EC3A007D4F1B /* main.m in Sources */, 405 | E1B844C8206A0DCC007D4F1B /* KeyFrameAnimationViewController.m in Sources */, 406 | E1B844C22069FF64007D4F1B /* BaseAnimationViewController.m in Sources */, 407 | E1B844E2206A34A6007D4F1B /* MCFireworksButton.m in Sources */, 408 | E1B8448F2069EC3A007D4F1B /* AppDelegate.m in Sources */, 409 | ); 410 | runOnlyForDeploymentPostprocessing = 0; 411 | }; 412 | E1B8449E2069EC3A007D4F1B /* Sources */ = { 413 | isa = PBXSourcesBuildPhase; 414 | buildActionMask = 2147483647; 415 | files = ( 416 | E1B844A72069EC3A007D4F1B /* BabyPigAnimationTests.m in Sources */, 417 | ); 418 | runOnlyForDeploymentPostprocessing = 0; 419 | }; 420 | E1B844A92069EC3A007D4F1B /* Sources */ = { 421 | isa = PBXSourcesBuildPhase; 422 | buildActionMask = 2147483647; 423 | files = ( 424 | E1B844B22069EC3A007D4F1B /* BabyPigAnimationUITests.m in Sources */, 425 | ); 426 | runOnlyForDeploymentPostprocessing = 0; 427 | }; 428 | /* End PBXSourcesBuildPhase section */ 429 | 430 | /* Begin PBXTargetDependency section */ 431 | E1B844A42069EC3A007D4F1B /* PBXTargetDependency */ = { 432 | isa = PBXTargetDependency; 433 | target = E1B844892069EC3A007D4F1B /* BabyPigAnimation */; 434 | targetProxy = E1B844A32069EC3A007D4F1B /* PBXContainerItemProxy */; 435 | }; 436 | E1B844AF2069EC3A007D4F1B /* PBXTargetDependency */ = { 437 | isa = PBXTargetDependency; 438 | target = E1B844892069EC3A007D4F1B /* BabyPigAnimation */; 439 | targetProxy = E1B844AE2069EC3A007D4F1B /* PBXContainerItemProxy */; 440 | }; 441 | /* End PBXTargetDependency section */ 442 | 443 | /* Begin PBXVariantGroup section */ 444 | E1B844932069EC3A007D4F1B /* Main.storyboard */ = { 445 | isa = PBXVariantGroup; 446 | children = ( 447 | E1B844942069EC3A007D4F1B /* Base */, 448 | ); 449 | name = Main.storyboard; 450 | sourceTree = ""; 451 | }; 452 | E1B844982069EC3A007D4F1B /* LaunchScreen.storyboard */ = { 453 | isa = PBXVariantGroup; 454 | children = ( 455 | E1B844992069EC3A007D4F1B /* Base */, 456 | ); 457 | name = LaunchScreen.storyboard; 458 | sourceTree = ""; 459 | }; 460 | /* End PBXVariantGroup section */ 461 | 462 | /* Begin XCBuildConfiguration section */ 463 | E1B844B42069EC3A007D4F1B /* Debug */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ALWAYS_SEARCH_USER_PATHS = NO; 467 | CLANG_ANALYZER_NONNULL = YES; 468 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 469 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 470 | CLANG_CXX_LIBRARY = "libc++"; 471 | CLANG_ENABLE_MODULES = YES; 472 | CLANG_ENABLE_OBJC_ARC = YES; 473 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 474 | CLANG_WARN_BOOL_CONVERSION = YES; 475 | CLANG_WARN_COMMA = YES; 476 | CLANG_WARN_CONSTANT_CONVERSION = YES; 477 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 478 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 479 | CLANG_WARN_EMPTY_BODY = YES; 480 | CLANG_WARN_ENUM_CONVERSION = YES; 481 | CLANG_WARN_INFINITE_RECURSION = YES; 482 | CLANG_WARN_INT_CONVERSION = YES; 483 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 484 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 485 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 486 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 487 | CLANG_WARN_STRICT_PROTOTYPES = YES; 488 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 489 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 490 | CLANG_WARN_UNREACHABLE_CODE = YES; 491 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 492 | CODE_SIGN_IDENTITY = "iPhone Developer"; 493 | COPY_PHASE_STRIP = NO; 494 | DEBUG_INFORMATION_FORMAT = dwarf; 495 | ENABLE_STRICT_OBJC_MSGSEND = YES; 496 | ENABLE_TESTABILITY = YES; 497 | GCC_C_LANGUAGE_STANDARD = gnu11; 498 | GCC_DYNAMIC_NO_PIC = NO; 499 | GCC_NO_COMMON_BLOCKS = YES; 500 | GCC_OPTIMIZATION_LEVEL = 0; 501 | GCC_PREPROCESSOR_DEFINITIONS = ( 502 | "DEBUG=1", 503 | "$(inherited)", 504 | ); 505 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 506 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 507 | GCC_WARN_UNDECLARED_SELECTOR = YES; 508 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 509 | GCC_WARN_UNUSED_FUNCTION = YES; 510 | GCC_WARN_UNUSED_VARIABLE = YES; 511 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 512 | MTL_ENABLE_DEBUG_INFO = YES; 513 | ONLY_ACTIVE_ARCH = YES; 514 | SDKROOT = iphoneos; 515 | }; 516 | name = Debug; 517 | }; 518 | E1B844B52069EC3A007D4F1B /* Release */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | ALWAYS_SEARCH_USER_PATHS = NO; 522 | CLANG_ANALYZER_NONNULL = YES; 523 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 524 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 525 | CLANG_CXX_LIBRARY = "libc++"; 526 | CLANG_ENABLE_MODULES = YES; 527 | CLANG_ENABLE_OBJC_ARC = YES; 528 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 529 | CLANG_WARN_BOOL_CONVERSION = YES; 530 | CLANG_WARN_COMMA = YES; 531 | CLANG_WARN_CONSTANT_CONVERSION = YES; 532 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 533 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 534 | CLANG_WARN_EMPTY_BODY = YES; 535 | CLANG_WARN_ENUM_CONVERSION = YES; 536 | CLANG_WARN_INFINITE_RECURSION = YES; 537 | CLANG_WARN_INT_CONVERSION = YES; 538 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 539 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 540 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 541 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 542 | CLANG_WARN_STRICT_PROTOTYPES = YES; 543 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 544 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 545 | CLANG_WARN_UNREACHABLE_CODE = YES; 546 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 547 | CODE_SIGN_IDENTITY = "iPhone Developer"; 548 | COPY_PHASE_STRIP = NO; 549 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 550 | ENABLE_NS_ASSERTIONS = NO; 551 | ENABLE_STRICT_OBJC_MSGSEND = YES; 552 | GCC_C_LANGUAGE_STANDARD = gnu11; 553 | GCC_NO_COMMON_BLOCKS = YES; 554 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 555 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 556 | GCC_WARN_UNDECLARED_SELECTOR = YES; 557 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 558 | GCC_WARN_UNUSED_FUNCTION = YES; 559 | GCC_WARN_UNUSED_VARIABLE = YES; 560 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 561 | MTL_ENABLE_DEBUG_INFO = NO; 562 | SDKROOT = iphoneos; 563 | VALIDATE_PRODUCT = YES; 564 | }; 565 | name = Release; 566 | }; 567 | E1B844B72069EC3A007D4F1B /* Debug */ = { 568 | isa = XCBuildConfiguration; 569 | buildSettings = { 570 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 571 | CODE_SIGN_STYLE = Automatic; 572 | DEVELOPMENT_TEAM = NS2J6E32M9; 573 | INFOPLIST_FILE = BabyPigAnimation/Info.plist; 574 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 575 | PRODUCT_BUNDLE_IDENTIFIER = com.gaojun.BabyPigAnimation; 576 | PRODUCT_NAME = "$(TARGET_NAME)"; 577 | TARGETED_DEVICE_FAMILY = "1,2"; 578 | }; 579 | name = Debug; 580 | }; 581 | E1B844B82069EC3A007D4F1B /* Release */ = { 582 | isa = XCBuildConfiguration; 583 | buildSettings = { 584 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 585 | CODE_SIGN_STYLE = Automatic; 586 | DEVELOPMENT_TEAM = NS2J6E32M9; 587 | INFOPLIST_FILE = BabyPigAnimation/Info.plist; 588 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 589 | PRODUCT_BUNDLE_IDENTIFIER = com.gaojun.BabyPigAnimation; 590 | PRODUCT_NAME = "$(TARGET_NAME)"; 591 | TARGETED_DEVICE_FAMILY = "1,2"; 592 | }; 593 | name = Release; 594 | }; 595 | E1B844BA2069EC3A007D4F1B /* Debug */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | BUNDLE_LOADER = "$(TEST_HOST)"; 599 | CODE_SIGN_STYLE = Automatic; 600 | DEVELOPMENT_TEAM = NS2J6E32M9; 601 | INFOPLIST_FILE = BabyPigAnimationTests/Info.plist; 602 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 603 | PRODUCT_BUNDLE_IDENTIFIER = com.gaojun.BabyPigAnimationTests; 604 | PRODUCT_NAME = "$(TARGET_NAME)"; 605 | TARGETED_DEVICE_FAMILY = "1,2"; 606 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BabyPigAnimation.app/BabyPigAnimation"; 607 | }; 608 | name = Debug; 609 | }; 610 | E1B844BB2069EC3A007D4F1B /* Release */ = { 611 | isa = XCBuildConfiguration; 612 | buildSettings = { 613 | BUNDLE_LOADER = "$(TEST_HOST)"; 614 | CODE_SIGN_STYLE = Automatic; 615 | DEVELOPMENT_TEAM = NS2J6E32M9; 616 | INFOPLIST_FILE = BabyPigAnimationTests/Info.plist; 617 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 618 | PRODUCT_BUNDLE_IDENTIFIER = com.gaojun.BabyPigAnimationTests; 619 | PRODUCT_NAME = "$(TARGET_NAME)"; 620 | TARGETED_DEVICE_FAMILY = "1,2"; 621 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BabyPigAnimation.app/BabyPigAnimation"; 622 | }; 623 | name = Release; 624 | }; 625 | E1B844BD2069EC3A007D4F1B /* Debug */ = { 626 | isa = XCBuildConfiguration; 627 | buildSettings = { 628 | CODE_SIGN_STYLE = Automatic; 629 | DEVELOPMENT_TEAM = NS2J6E32M9; 630 | INFOPLIST_FILE = BabyPigAnimationUITests/Info.plist; 631 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 632 | PRODUCT_BUNDLE_IDENTIFIER = com.gaojun.BabyPigAnimationUITests; 633 | PRODUCT_NAME = "$(TARGET_NAME)"; 634 | TARGETED_DEVICE_FAMILY = "1,2"; 635 | TEST_TARGET_NAME = BabyPigAnimation; 636 | }; 637 | name = Debug; 638 | }; 639 | E1B844BE2069EC3A007D4F1B /* Release */ = { 640 | isa = XCBuildConfiguration; 641 | buildSettings = { 642 | CODE_SIGN_STYLE = Automatic; 643 | DEVELOPMENT_TEAM = NS2J6E32M9; 644 | INFOPLIST_FILE = BabyPigAnimationUITests/Info.plist; 645 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 646 | PRODUCT_BUNDLE_IDENTIFIER = com.gaojun.BabyPigAnimationUITests; 647 | PRODUCT_NAME = "$(TARGET_NAME)"; 648 | TARGETED_DEVICE_FAMILY = "1,2"; 649 | TEST_TARGET_NAME = BabyPigAnimation; 650 | }; 651 | name = Release; 652 | }; 653 | /* End XCBuildConfiguration section */ 654 | 655 | /* Begin XCConfigurationList section */ 656 | E1B844852069EC3A007D4F1B /* Build configuration list for PBXProject "BabyPigAnimation" */ = { 657 | isa = XCConfigurationList; 658 | buildConfigurations = ( 659 | E1B844B42069EC3A007D4F1B /* Debug */, 660 | E1B844B52069EC3A007D4F1B /* Release */, 661 | ); 662 | defaultConfigurationIsVisible = 0; 663 | defaultConfigurationName = Release; 664 | }; 665 | E1B844B62069EC3A007D4F1B /* Build configuration list for PBXNativeTarget "BabyPigAnimation" */ = { 666 | isa = XCConfigurationList; 667 | buildConfigurations = ( 668 | E1B844B72069EC3A007D4F1B /* Debug */, 669 | E1B844B82069EC3A007D4F1B /* Release */, 670 | ); 671 | defaultConfigurationIsVisible = 0; 672 | defaultConfigurationName = Release; 673 | }; 674 | E1B844B92069EC3A007D4F1B /* Build configuration list for PBXNativeTarget "BabyPigAnimationTests" */ = { 675 | isa = XCConfigurationList; 676 | buildConfigurations = ( 677 | E1B844BA2069EC3A007D4F1B /* Debug */, 678 | E1B844BB2069EC3A007D4F1B /* Release */, 679 | ); 680 | defaultConfigurationIsVisible = 0; 681 | defaultConfigurationName = Release; 682 | }; 683 | E1B844BC2069EC3A007D4F1B /* Build configuration list for PBXNativeTarget "BabyPigAnimationUITests" */ = { 684 | isa = XCConfigurationList; 685 | buildConfigurations = ( 686 | E1B844BD2069EC3A007D4F1B /* Debug */, 687 | E1B844BE2069EC3A007D4F1B /* Release */, 688 | ); 689 | defaultConfigurationIsVisible = 0; 690 | defaultConfigurationName = Release; 691 | }; 692 | /* End XCConfigurationList section */ 693 | }; 694 | rootObject = E1B844822069EC3A007D4F1B /* Project object */; 695 | } 696 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation.xcodeproj/project.xcworkspace/xcuserdata/gaojun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation.xcodeproj/project.xcworkspace/xcuserdata/gaojun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation.xcodeproj/xcuserdata/gaojun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation.xcodeproj/xcuserdata/gaojun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BabyPigAnimation.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/.DS_Store -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // AppDelegate.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // AppDelegate.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "AppDelegate.h" 12 | #import "ViewController.h" 13 | 14 | @interface AppDelegate () 15 | 16 | @end 17 | 18 | @implementation AppDelegate 19 | 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | // Override point for customization after application launch. 23 | 24 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]]; 25 | self.window.rootViewController = nav; 26 | [self.window makeKeyAndVisible]; 27 | 28 | return YES; 29 | } 30 | 31 | 32 | - (void)applicationWillResignActive:(UIApplication *)application { 33 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 34 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 35 | } 36 | 37 | 38 | - (void)applicationDidEnterBackground:(UIApplication *)application { 39 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | } 42 | 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application { 45 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 46 | } 47 | 48 | 49 | - (void)applicationDidBecomeActive:(UIApplication *)application { 50 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 51 | } 52 | 53 | 54 | - (void)applicationWillTerminate:(UIApplication *)application { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Like-Blue.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Like-Blue@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Like-Blue.imageset/Like-Blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Like-Blue.imageset/Like-Blue@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Like.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Like@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Like.imageset/Like@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Like.imageset/Like@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Sparkle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Sparkle.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Sparkle.imageset/Sparkle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/Sparkle.imageset/Sparkle.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-input-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-button-input-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-input-highlighted.imageset/chooser-button-input-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-input-highlighted.imageset/chooser-button-input-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-input.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-button-input@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-input.imageset/chooser-button-input@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-input.imageset/chooser-button-input@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-tab-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-button-tab-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-tab-highlighted.imageset/chooser-button-tab-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-tab-highlighted.imageset/chooser-button-tab-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-tab.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-button-tab@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-tab.imageset/chooser-button-tab@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-button-tab.imageset/chooser-button-tab@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-button-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-button-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-button-highlighted.imageset/chooser-moment-button-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-button-highlighted.imageset/chooser-moment-button-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-button@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-button.imageset/chooser-moment-button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-button.imageset/chooser-moment-button@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-camera-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-camera-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-camera-highlighted.imageset/chooser-moment-icon-camera-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-camera-highlighted.imageset/chooser-moment-icon-camera-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-camera.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-camera@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-camera.imageset/chooser-moment-icon-camera@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-camera.imageset/chooser-moment-icon-camera@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-music-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-music-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-music-highlighted.imageset/chooser-moment-icon-music-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-music-highlighted.imageset/chooser-moment-icon-music-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-music.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-music@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-music.imageset/chooser-moment-icon-music@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-music.imageset/chooser-moment-icon-music@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-place-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-place-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-place-highlighted.imageset/chooser-moment-icon-place-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-place-highlighted.imageset/chooser-moment-icon-place-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-place.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-place@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-place.imageset/chooser-moment-icon-place@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-place.imageset/chooser-moment-icon-place@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-sleep-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-sleep-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-sleep-highlighted.imageset/chooser-moment-icon-sleep-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-sleep-highlighted.imageset/chooser-moment-icon-sleep-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-sleep.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-sleep@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-sleep.imageset/chooser-moment-icon-sleep@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-sleep.imageset/chooser-moment-icon-sleep@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-thought-highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-thought-highlighted@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-thought-highlighted.imageset/chooser-moment-icon-thought-highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-thought-highlighted.imageset/chooser-moment-icon-thought-highlighted@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-thought.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "chooser-moment-icon-thought@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-thought.imageset/chooser-moment-icon-thought@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Assets.xcassets/chooser-moment-icon-thought.imageset/chooser-moment-icon-thought@2x.png -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/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 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DCPathButton/DCPathButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCPathButton.h 3 | // DCPathButton 4 | // 5 | // Created by tang dixi on 30/7/14. 6 | // Copyright (c) 2014 Tangdxi. All rights reserved. 7 | // 8 | 9 | #import "DCPathItemButton.h" 10 | 11 | @import UIKit; 12 | @import QuartzCore; 13 | @import AudioToolbox; 14 | 15 | @protocol DCPathButtonDelegate 16 | 17 | - (void)itemButtonTappedAtIndex:(NSUInteger)index; 18 | 19 | @end 20 | 21 | @interface DCPathButton : UIView 22 | 23 | @property (weak, nonatomic) id delegate; 24 | 25 | @property (strong, nonatomic) NSMutableArray *itemButtonImages; 26 | @property (strong, nonatomic) NSMutableArray *itemButtonHighlightedImages; 27 | 28 | @property (strong, nonatomic) UIImage *itemButtonBackgroundImage; 29 | @property (strong, nonatomic) UIImage *itemButtonBackgroundHighlightedImage; 30 | 31 | @property (assign, nonatomic) CGFloat bloomRadius; 32 | 33 | - (id)initWithCenterImage:(UIImage *)centerImage hilightedImage:(UIImage *)centerHighlightedImage; 34 | - (void)addPathItems:(NSArray *)pathItemButtons; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DCPathButton/DCPathButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCPathButton.m 3 | // DCPathButton 4 | // 5 | // Created by tang dixi on 30/7/14. 6 | // Copyright (c) 2014 Tangdxi. All rights reserved. 7 | // 8 | 9 | #import "DCPathButton.h" 10 | #import "DCPathCenterButton.h" 11 | 12 | @interface DCPathButton () 13 | 14 | #pragma mark - Private Property 15 | 16 | @property (strong, nonatomic) UIImage *centerImage; 17 | @property (strong, nonatomic) UIImage *centerHighlightedImage; 18 | 19 | @property (assign, nonatomic, getter = isBloom) BOOL bloom; 20 | 21 | @property (assign, nonatomic) CGSize foldedSize; 22 | @property (assign, nonatomic) CGSize bloomSize; 23 | 24 | @property (assign, nonatomic) CGPoint foldCenter; 25 | @property (assign, nonatomic) CGPoint bloomCenter; 26 | 27 | @property (assign, nonatomic) CGPoint pathCenterButtonBloomCenter; 28 | 29 | @property (assign, nonatomic) CGPoint expandCenter; 30 | @property (strong, nonatomic) UIView *bottomView; 31 | @property (strong, nonatomic) DCPathCenterButton *pathCenterButton; 32 | @property (strong, nonatomic) NSMutableArray *itemButtons; 33 | 34 | @property (assign, nonatomic) SystemSoundID bloomSound; 35 | @property (assign, nonatomic) SystemSoundID foldSound; 36 | @property (assign, nonatomic) SystemSoundID selectedSound; 37 | 38 | 39 | @end 40 | 41 | @implementation DCPathButton 42 | 43 | #pragma mark - Initialization 44 | 45 | - (id)initWithCenterImage:(UIImage *)centerImage hilightedImage:(UIImage *)centerHighlightedImage 46 | { 47 | if (self = [super init]) { 48 | 49 | // Configure center and high light center image 50 | // 51 | self.centerImage = centerImage; 52 | self.centerHighlightedImage = centerHighlightedImage; 53 | 54 | // Init button and image array 55 | // 56 | self.itemButtonImages = [[NSMutableArray alloc]init]; 57 | self.itemButtonHighlightedImages = [[NSMutableArray alloc]init]; 58 | self.itemButtons = [[NSMutableArray alloc]init]; 59 | 60 | // Configure views 61 | // 62 | [self configureViewsLayout]; 63 | 64 | // Configure sounds 65 | // 66 | [self configureSounds]; 67 | } 68 | return self; 69 | } 70 | 71 | - (void)configureViewsLayout 72 | { 73 | // Init some property only once 74 | // 75 | self.foldedSize = self.centerImage.size; 76 | self.bloomSize = [UIScreen mainScreen].bounds.size; 77 | 78 | self.bloom = NO; 79 | self.bloomRadius = 105.0f; 80 | 81 | // Configure the view's center, it will change after the frame folded or bloomed 82 | //景铭修改过了,原来self.foldCenter = CGPointMake(self.bloomSize.width / 2, self.bloomSize.height - 25.5f); 83 | self.foldCenter = CGPointMake(self.bloomSize.width / 2, self.bloomSize.height - 225.5f); 84 | self.bloomCenter = CGPointMake(self.bloomSize.width / 2, self.bloomSize.height / 2); 85 | 86 | // Configure the DCPathButton's origin frame 87 | // 88 | self.frame = CGRectMake(0, 0, self.foldedSize.width, self.foldedSize.height); 89 | self.center = self.foldCenter; 90 | 91 | // Configure center button 92 | // 93 | _pathCenterButton = [[DCPathCenterButton alloc]initWithImage:self.centerImage highlightedImage:self.centerHighlightedImage]; 94 | _pathCenterButton.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); 95 | _pathCenterButton.delegate = self; 96 | [self addSubview:_pathCenterButton]; 97 | 98 | // Configure bottom view 99 | // 100 | _bottomView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.bloomSize.width, self.bloomSize.height)]; 101 | _bottomView.backgroundColor = [UIColor blackColor]; 102 | _bottomView.alpha = 0.0f; 103 | 104 | } 105 | 106 | 107 | - (void)configureSounds 108 | { 109 | // Configure bloom sound 110 | // 111 | NSString *bloomSoundPath = [[NSBundle mainBundle]pathForResource:@"bloom" ofType:@"caf"]; 112 | NSURL *bloomSoundURL = [NSURL fileURLWithPath:bloomSoundPath]; 113 | AudioServicesCreateSystemSoundID((__bridge CFURLRef)bloomSoundURL, &_bloomSound); 114 | 115 | // Configure fold sound 116 | // 117 | NSString *foldSoundPath = [[NSBundle mainBundle]pathForResource:@"fold" ofType:@"caf"]; 118 | NSURL *foldSoundURL = [NSURL fileURLWithPath:foldSoundPath]; 119 | AudioServicesCreateSystemSoundID((__bridge CFURLRef)foldSoundURL, &_foldSound); 120 | 121 | // Configure selected sound 122 | // 123 | NSString *selectedSoundPath = [[NSBundle mainBundle]pathForResource:@"selected" ofType:@"caf"]; 124 | NSURL *selectedSoundURL = [NSURL fileURLWithPath:selectedSoundPath]; 125 | AudioServicesCreateSystemSoundID((__bridge CFURLRef)selectedSoundURL, &_selectedSound); 126 | 127 | } 128 | 129 | #pragma mark - Configure Center Button Images 130 | 131 | - (void)setCenterImage:(UIImage *)centerImage 132 | { 133 | if (!centerImage) { 134 | NSLog(@"Load center image failed ... "); 135 | return ; 136 | } 137 | _centerImage = centerImage; 138 | } 139 | 140 | - (void)setCenterHighlightedImage:(UIImage *)highlightedImage 141 | { 142 | if (!highlightedImage) { 143 | NSLog(@"Load highted image failed ... "); 144 | return ; 145 | } 146 | _centerHighlightedImage = highlightedImage; 147 | } 148 | 149 | #pragma mark - Configure Expand Center Point 150 | 151 | - (void)setPathCenterButtonBloomCenter:(CGPoint)centerButtonBloomCenter 152 | { 153 | // Just set the bloom center once 154 | // 155 | if (_pathCenterButtonBloomCenter.x == 0) { 156 | _pathCenterButtonBloomCenter = centerButtonBloomCenter; 157 | } 158 | return ; 159 | } 160 | 161 | #pragma mark - Expand Status 162 | 163 | - (BOOL)isBloom 164 | { 165 | return _bloom; 166 | } 167 | 168 | #pragma mark - Center Button Delegate 169 | 170 | - (void)centerButtonTapped 171 | { 172 | self.isBloom? [self pathCenterButtonFold] : [self pathCenterButtonBloom]; 173 | } 174 | 175 | #pragma mark - Caculate The Item's End Point 176 | 177 | - (CGPoint)createEndPointWithRadius:(CGFloat)itemExpandRadius andAngel:(CGFloat)angel 178 | { 179 | return CGPointMake(self.pathCenterButtonBloomCenter.x - cosf(angel * M_PI) * itemExpandRadius, 180 | self.pathCenterButtonBloomCenter.y - sinf(angel * M_PI) * itemExpandRadius); 181 | } 182 | 183 | #pragma mark - Center Button Fold 184 | 185 | - (void)pathCenterButtonFold 186 | { 187 | // Play fold sound 188 | // 189 | AudioServicesPlaySystemSound(self.foldSound); 190 | 191 | // Load item buttons from array 192 | // 193 | for (int i = 1; i <= self.itemButtons.count; i++) { 194 | 195 | DCPathItemButton *itemButton = self.itemButtons[i - 1]; 196 | 197 | CGFloat currentAngel = i / ((CGFloat)self.itemButtons.count + 1); 198 | CGPoint farPoint = [self createEndPointWithRadius:self.bloomRadius + 5.0f andAngel:currentAngel]; 199 | 200 | CAAnimationGroup *foldAnimation = [self foldAnimationFromPoint:itemButton.center withFarPoint:farPoint]; 201 | 202 | [itemButton.layer addAnimation:foldAnimation forKey:@"foldAnimation"]; 203 | itemButton.center = self.pathCenterButtonBloomCenter; 204 | 205 | } 206 | 207 | [self bringSubviewToFront:self.pathCenterButton]; 208 | 209 | // Resize the DCPathButton's frame to the foled frame and remove the item buttons 210 | // 211 | [self resizeToFoldedFrame]; 212 | 213 | } 214 | 215 | - (void)resizeToFoldedFrame 216 | { 217 | [UIView animateWithDuration:0.0618f * 3 218 | delay:0.0618f * 2 219 | options:UIViewAnimationOptionCurveEaseIn 220 | animations:^{ 221 | _pathCenterButton.transform = CGAffineTransformMakeRotation(0); 222 | } 223 | completion:nil]; 224 | 225 | [UIView animateWithDuration:0.1f 226 | delay:0.35f 227 | options:UIViewAnimationOptionCurveLinear 228 | animations:^{ 229 | _bottomView.alpha = 0.0f; 230 | } 231 | completion:nil]; 232 | 233 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 234 | for (DCPathItemButton *itemButton in self.itemButtons) { 235 | [itemButton performSelector:@selector(removeFromSuperview)]; 236 | } 237 | 238 | self.frame = CGRectMake(0, 0, self.foldedSize.width, self.foldedSize.height); 239 | self.center = self.foldCenter; 240 | self.pathCenterButton.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); 241 | 242 | [self.bottomView removeFromSuperview]; 243 | }); 244 | 245 | _bloom = NO; 246 | } 247 | 248 | - (CAAnimationGroup *)foldAnimationFromPoint:(CGPoint)endPoint withFarPoint:(CGPoint)farPoint 249 | { 250 | // 1.Configure rotation animation 251 | // 252 | CAKeyframeAnimation *rotationAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 253 | rotationAnimation.values = @[@(0), @(M_PI), @(M_PI * 2)]; 254 | rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 255 | rotationAnimation.duration = 0.35f; 256 | 257 | // 2.Configure moving animation 258 | // 259 | CAKeyframeAnimation *movingAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 260 | 261 | // Create moving path 262 | // 263 | CGMutablePathRef path = CGPathCreateMutable(); 264 | CGPathMoveToPoint(path, NULL, endPoint.x, endPoint.y); 265 | CGPathAddLineToPoint(path, NULL, farPoint.x, farPoint.y); 266 | CGPathAddLineToPoint(path, NULL, self.pathCenterButtonBloomCenter.x, self.pathCenterButtonBloomCenter.y); 267 | 268 | movingAnimation.keyTimes = @[@(0.0f), @(0.75), @(1.0)]; 269 | 270 | movingAnimation.path = path; 271 | movingAnimation.duration = 0.35f; 272 | CGPathRelease(path); 273 | 274 | // 3.Merge animation together 275 | // 276 | CAAnimationGroup *animations = [CAAnimationGroup animation]; 277 | animations.animations = @[rotationAnimation, movingAnimation]; 278 | animations.duration = 0.35f; 279 | 280 | return animations; 281 | } 282 | 283 | #pragma mark - Center Button Bloom 284 | 285 | - (void)pathCenterButtonBloom 286 | { 287 | // Play bloom sound 288 | // 289 | AudioServicesPlaySystemSound(self.bloomSound); 290 | 291 | // Configure center button bloom 292 | // 293 | // 1. Store the current center point to 'centerButtonBloomCenter 294 | // 295 | self.pathCenterButtonBloomCenter = self.center; 296 | 297 | // 2. Resize the DCPathButton's frame 298 | // 299 | self.frame = CGRectMake(0, 0, self.bloomSize.width, self.bloomSize.height); 300 | self.center = CGPointMake(self.bloomSize.width / 2, self.bloomSize.height / 2); 301 | 302 | [self insertSubview:self.bottomView belowSubview:self.pathCenterButton]; 303 | 304 | // 3. Excute the bottom view alpha animation 305 | // 306 | [UIView animateWithDuration:0.0618f * 3 307 | delay:0.0f 308 | options:UIViewAnimationOptionCurveEaseIn 309 | animations:^{ 310 | _bottomView.alpha = 0.618f; 311 | } 312 | completion:nil]; 313 | 314 | // 4. Excute the center button rotation animation 315 | // 316 | [UIView animateWithDuration:0.1575f 317 | animations:^{ 318 | _pathCenterButton.transform = CGAffineTransformMakeRotation(-0.75f * M_PI); 319 | }]; 320 | 321 | self.pathCenterButton.center = self.pathCenterButtonBloomCenter; 322 | 323 | // 5. Excute the bloom animation 324 | // 325 | CGFloat basicAngel = 180 / (self.itemButtons.count + 1) ; 326 | 327 | for (int i = 1; i <= self.itemButtons.count; i++) { 328 | 329 | DCPathItemButton *pathItemButton = self.itemButtons[i - 1]; 330 | 331 | pathItemButton.delegate = self; 332 | pathItemButton.tag = i - 1; 333 | pathItemButton.transform = CGAffineTransformMakeTranslation(1, 1); 334 | pathItemButton.alpha = 1.0f; 335 | 336 | // 1. Add pathItem button to the view 337 | // 338 | CGFloat currentAngel = (basicAngel * i)/180; 339 | 340 | pathItemButton.center = self.pathCenterButtonBloomCenter; 341 | 342 | [self insertSubview:pathItemButton belowSubview:self.pathCenterButton]; 343 | 344 | // 2.Excute expand animation 345 | // 346 | CGPoint endPoint = [self createEndPointWithRadius:self.bloomRadius andAngel:currentAngel]; 347 | CGPoint farPoint = [self createEndPointWithRadius:self.bloomRadius + 10.0f andAngel:currentAngel]; 348 | CGPoint nearPoint = [self createEndPointWithRadius:self.bloomRadius - 5.0f andAngel:currentAngel]; 349 | 350 | CAAnimationGroup *bloomAnimation = [self bloomAnimationWithEndPoint:endPoint 351 | andFarPoint:farPoint 352 | andNearPoint:nearPoint]; 353 | 354 | [pathItemButton.layer addAnimation:bloomAnimation forKey:@"bloomAnimation"]; 355 | pathItemButton.center = endPoint; 356 | 357 | } 358 | 359 | _bloom = YES; 360 | 361 | } 362 | 363 | - (CAAnimationGroup *)bloomAnimationWithEndPoint:(CGPoint)endPoint andFarPoint:(CGPoint)farPoint andNearPoint:(CGPoint)nearPoint 364 | { 365 | // 1.Configure rotation animation 366 | // 367 | CAKeyframeAnimation *rotationAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 368 | rotationAnimation.values = @[@(0.0), @(- M_PI), @(- M_PI * 1.5), @(- M_PI * 2)]; 369 | rotationAnimation.duration = 0.3f; 370 | rotationAnimation.keyTimes = @[@(0.0), @(0.3), @(0.6), @(1.0)]; 371 | 372 | // 2.Configure moving animation 373 | // 374 | CAKeyframeAnimation *movingAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 375 | 376 | // Create moving path 377 | // 378 | CGMutablePathRef path = CGPathCreateMutable(); 379 | CGPathMoveToPoint(path, NULL, self.pathCenterButtonBloomCenter.x, self.pathCenterButtonBloomCenter.y); 380 | CGPathAddLineToPoint(path, NULL, farPoint.x, farPoint.y); 381 | CGPathAddLineToPoint(path, NULL, nearPoint.x, nearPoint.y); 382 | CGPathAddLineToPoint(path, NULL, endPoint.x, endPoint.y); 383 | 384 | movingAnimation.path = path; 385 | movingAnimation.keyTimes = @[@(0.0), @(0.5), @(0.7), @(1.0)]; 386 | movingAnimation.duration = 0.3f; 387 | CGPathRelease(path); 388 | 389 | // 3.Merge two animation together 390 | // 391 | CAAnimationGroup *animations = [CAAnimationGroup animation]; 392 | animations.animations = @[movingAnimation, rotationAnimation]; 393 | animations.duration = 0.3f; 394 | animations.delegate = self; 395 | 396 | return animations; 397 | } 398 | 399 | #pragma mark - Add PathButton Item 400 | 401 | - (void)addPathItems:(NSArray *)pathItemButtons 402 | { 403 | [self.itemButtons addObjectsFromArray:pathItemButtons]; 404 | } 405 | 406 | #pragma mark - DCPathButton Touch Events 407 | 408 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 409 | { 410 | // Tap the bottom area, excute the fold animation 411 | [self pathCenterButtonFold]; 412 | } 413 | 414 | #pragma mark - DCPathButton Item Delegate 415 | 416 | - (void)itemButtonTapped:(DCPathItemButton *)itemButton 417 | { 418 | if ([_delegate respondsToSelector:@selector(itemButtonTappedAtIndex:)]) { 419 | 420 | DCPathItemButton *selectedButton = self.itemButtons[itemButton.tag]; 421 | 422 | // Play selected sound 423 | // 424 | AudioServicesPlaySystemSound(self.selectedSound); 425 | 426 | // Excute the explode animation when the item is seleted 427 | // 428 | [UIView animateWithDuration:0.0618f * 5 429 | animations:^{ 430 | selectedButton.transform = CGAffineTransformMakeScale(3, 3); 431 | selectedButton.alpha = 0.0f; 432 | }]; 433 | 434 | // Excute the dismiss animation when the item is unselected 435 | // 436 | for (int i = 0; i < self.itemButtons.count; i++) { 437 | if (i == selectedButton.tag) { 438 | continue; 439 | } 440 | DCPathItemButton *unselectedButton = self.itemButtons[i]; 441 | [UIView animateWithDuration:0.0618f * 2 442 | animations:^{ 443 | unselectedButton.transform = CGAffineTransformMakeScale(0, 0); 444 | }]; 445 | } 446 | 447 | // Excute the delegate method 448 | // 449 | [_delegate itemButtonTappedAtIndex:itemButton.tag]; 450 | 451 | // Resize the DCPathButton's frame 452 | // 453 | [self resizeToFoldedFrame]; 454 | } 455 | } 456 | 457 | @end 458 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DCPathButton/DCPathCenterButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCPathCenterButton.h 3 | // DCPathButton 4 | // 5 | // Created by tang dixi on 30/7/14. 6 | // Copyright (c) 2014 Tangdxi. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @protocol DCPathCenterButtonDelegate 12 | 13 | - (void)centerButtonTapped; 14 | 15 | @end 16 | 17 | @interface DCPathCenterButton : UIImageView 18 | 19 | @property (weak, nonatomic) id delegate; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DCPathButton/DCPathCenterButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCPathCenterButton.m 3 | // DCPathButton 4 | // 5 | // Created by tang dixi on 30/7/14. 6 | // Copyright (c) 2014 Tangdxi. All rights reserved. 7 | // 8 | 9 | #import "DCPathCenterButton.h" 10 | 11 | @implementation DCPathCenterButton 12 | 13 | - (id)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage 14 | { 15 | if (self = [super initWithImage:image highlightedImage:highlightedImage]) { 16 | 17 | self.userInteractionEnabled = YES; 18 | 19 | self.image = image; 20 | self.highlightedImage = highlightedImage; 21 | 22 | } 23 | return self; 24 | } 25 | 26 | #pragma mark - Scale Center Button Frame to 5x 27 | 28 | - (CGRect)scaleRect:(CGRect)originRect 29 | { 30 | return CGRectMake(- originRect.size.width, 31 | - originRect.size.height, 32 | originRect.size.width * 3, 33 | originRect.size.height * 3); 34 | } 35 | 36 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 37 | { 38 | self.highlighted = YES; 39 | 40 | // Center button Begin Tapped 41 | if ([_delegate respondsToSelector:@selector(centerButtonTapped)]) { 42 | [_delegate centerButtonTapped]; 43 | } 44 | 45 | } 46 | 47 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 48 | { 49 | CGPoint currentLocation = [[touches anyObject]locationInView:self]; 50 | 51 | 52 | // Cancel button highlight when the touch location is out of 5x area 53 | // 54 | if (!CGRectContainsPoint([self scaleRect:self.bounds] , currentLocation)) { 55 | self.highlighted = NO; 56 | return ; 57 | } 58 | 59 | // If moving in the 3x area, keep the highlight state 60 | // 61 | self.highlighted = YES; 62 | } 63 | 64 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 65 | { 66 | self.highlighted = NO; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DCPathButton/DCPathItemButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // DCPathItemButton.h 3 | // DCPathButton 4 | // 5 | // Created by tang dixi on 31/7/14. 6 | // Copyright (c) 2014 Tangdxi. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @class DCPathItemButton; 12 | 13 | @protocol DCPathItemButtonDelegate 14 | 15 | - (void)itemButtonTapped:(DCPathItemButton *)itemButton; 16 | 17 | @end 18 | 19 | @interface DCPathItemButton : UIImageView 20 | 21 | @property (assign, nonatomic) NSUInteger index; 22 | @property (weak, nonatomic) id delegate; 23 | 24 | - (id)initWithImage:(UIImage *)image 25 | highlightedImage:(UIImage *)highlightedImage 26 | backgroundImage:(UIImage *)backgroundImage 27 | backgroundHighlightedImage:(UIImage *)backgroundHighlightedImage; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DCPathButton/DCPathItemButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // DCPathItemButton.m 3 | // DCPathButton 4 | // 5 | // Created by tang dixi on 31/7/14. 6 | // Copyright (c) 2014 Tangdxi. All rights reserved. 7 | // 8 | 9 | #import "DCPathItemButton.h" 10 | 11 | @interface DCPathItemButton () 12 | 13 | @property (strong, nonatomic) UIImageView *backgroundImageView; 14 | 15 | @end 16 | 17 | @implementation DCPathItemButton 18 | 19 | - (id)initWithImage:(UIImage *)image highlightedImage:(UIImage *)highlightedImage backgroundImage:(UIImage *)backgroundImage backgroundHighlightedImage:(UIImage *)backgroundHighlightedImage 20 | { 21 | if (self = [super init]) { 22 | 23 | // Make sure the iteam has a certain frame 24 | // 25 | CGRect itemFrame = CGRectMake(0, 0, backgroundImage.size.width, backgroundImage.size.height); 26 | 27 | if (!backgroundImage || !backgroundHighlightedImage) { 28 | itemFrame = CGRectMake(0, 0, image.size.width, image.size.height); 29 | } 30 | self.frame = itemFrame; 31 | 32 | // Configure the item image 33 | // 34 | self.image = backgroundImage; 35 | self.highlightedImage = backgroundHighlightedImage; 36 | 37 | self.userInteractionEnabled = YES; 38 | 39 | // Configure background 40 | // 41 | _backgroundImageView = [[UIImageView alloc]initWithImage:image 42 | highlightedImage:highlightedImage]; 43 | 44 | _backgroundImageView.center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); 45 | 46 | [self addSubview:_backgroundImageView]; 47 | 48 | } 49 | return self; 50 | } 51 | 52 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 53 | { 54 | self.highlighted = YES; 55 | self.backgroundImageView.highlighted = YES; 56 | } 57 | 58 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 59 | { 60 | CGPoint currentLocation = [[touches anyObject]locationInView:self]; 61 | 62 | if (! CGRectContainsPoint([self scaleRect:self.bounds], currentLocation)) { 63 | self.highlighted = NO; 64 | self.backgroundImageView.highlighted = NO; 65 | 66 | return ; 67 | } 68 | 69 | self.highlighted = YES; 70 | self.backgroundImageView.highlighted = YES; 71 | } 72 | 73 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 74 | { 75 | if ([_delegate respondsToSelector:@selector(itemButtonTapped:)]) { 76 | [_delegate itemButtonTapped:self]; 77 | } 78 | 79 | self.highlighted = NO; 80 | self.backgroundImageView.highlighted = NO; 81 | } 82 | 83 | #pragma mark - Scale Item Button 84 | 85 | - (CGRect)scaleRect:(CGRect)originRect 86 | { 87 | return CGRectMake(- originRect.size.width * 2, 88 | - originRect.size.height * 2, 89 | originRect.size.width * 5, 90 | originRect.size.height * 5); 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DWBubbleMenuButton/DWBubbleMenuButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // DWBubbleMenuButton.h 3 | // DWBubbleMenuButtonExample 4 | // 5 | // Created by Derrick Walker on 10/8/14. 6 | // Copyright (c) 2014 Derrick Walker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, ExpansionDirection) { 12 | DirectionLeft = 0, 13 | DirectionRight, 14 | DirectionUp, 15 | DirectionDown 16 | }; 17 | 18 | 19 | @class DWBubbleMenuButton; 20 | 21 | @protocol DWBubbleMenuViewDelegate 22 | 23 | @optional 24 | - (void)bubbleMenuButtonWillExpand:(DWBubbleMenuButton *)expandableView; 25 | - (void)bubbleMenuButtonDidExpand:(DWBubbleMenuButton *)expandableView; 26 | - (void)bubbleMenuButtonWillCollapse:(DWBubbleMenuButton *)expandableView; 27 | - (void)bubbleMenuButtonDidCollapse:(DWBubbleMenuButton *)expandableView; 28 | 29 | @end 30 | 31 | @interface DWBubbleMenuButton : UIView 32 | 33 | @property (nonatomic, weak, readonly) NSArray *buttons; 34 | @property (nonatomic, strong) UIView *homeButtonView; 35 | @property (nonatomic, readonly) BOOL isCollapsed; 36 | @property (nonatomic, weak) id delegate; 37 | 38 | // The direction in which the menu expands 39 | @property (nonatomic) enum ExpansionDirection direction; 40 | 41 | // Indicates whether the home button will animate it's touch highlighting, this is enabled by default 42 | @property (nonatomic) BOOL animatedHighlighting; 43 | 44 | // Indicates whether menu should collapse after a button selection, this is enabled by default 45 | @property (nonatomic) BOOL collapseAfterSelection; 46 | 47 | // The duration of the expand/collapse animation 48 | @property (nonatomic) float animationDuration; 49 | 50 | // The default alpha of the homeButtonView when not tapped 51 | @property (nonatomic) float standbyAlpha; 52 | 53 | // The highlighted alpha of the homeButtonView when tapped 54 | @property (nonatomic) float highlightAlpha; 55 | 56 | // The spacing between menu buttons when expanded 57 | @property (nonatomic) float buttonSpacing; 58 | 59 | // Initializers 60 | - (id)initWithFrame:(CGRect)frame expansionDirection:(ExpansionDirection)direction; 61 | 62 | // Public Methods 63 | - (void)addButtons:(NSArray *)buttons; 64 | - (void)addButton:(UIButton *)button; 65 | - (void)showButtons; 66 | - (void)dismissButtons; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/DWBubbleMenuButton/DWBubbleMenuButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // DWBubbleMenuButton.m 3 | // DWBubbleMenuButtonExample 4 | // 5 | // Created by Derrick Walker on 10/8/14. 6 | // Copyright (c) 2014 Derrick Walker. All rights reserved. 7 | // 8 | 9 | #import "DWBubbleMenuButton.h" 10 | 11 | #define kDefaultAnimationDuration 0.25f 12 | 13 | @interface DWBubbleMenuButton () 14 | 15 | @property (nonatomic, strong) UITapGestureRecognizer *tapGestureRecognizer; 16 | @property (nonatomic, strong) NSMutableArray *buttonContainer; 17 | @property (nonatomic, assign) CGRect originFrame; 18 | 19 | @end 20 | 21 | @implementation DWBubbleMenuButton 22 | 23 | #pragma mark - 24 | #pragma mark Public Methods 25 | 26 | - (void)addButtons:(NSArray *)buttons { 27 | assert(buttons != nil); 28 | for (UIButton *button in buttons) { 29 | [self addButton:button]; 30 | } 31 | 32 | if (self.homeButtonView != nil) { 33 | [self bringSubviewToFront:self.homeButtonView]; 34 | } 35 | } 36 | 37 | - (void)addButton:(UIButton *)button { 38 | assert(button != nil); 39 | if (_buttonContainer == nil) { 40 | self.buttonContainer = [[NSMutableArray alloc] init]; 41 | } 42 | 43 | if ([_buttonContainer containsObject:button] == false) { 44 | [_buttonContainer addObject:button]; 45 | [self addSubview:button]; 46 | button.hidden = YES; 47 | } 48 | } 49 | 50 | - (void)showButtons { 51 | if ([self.delegate respondsToSelector:@selector(bubbleMenuButtonWillExpand:)]) { 52 | [self.delegate bubbleMenuButtonWillExpand:self]; 53 | } 54 | 55 | [self _prepareForButtonExpansion]; 56 | 57 | self.userInteractionEnabled = NO; 58 | 59 | [CATransaction begin]; 60 | [CATransaction setAnimationDuration:_animationDuration]; 61 | [CATransaction setCompletionBlock:^{ 62 | for (UIButton *button in _buttonContainer) { 63 | button.transform = CGAffineTransformIdentity; 64 | } 65 | 66 | if (self.delegate != nil) { 67 | if ([self.delegate respondsToSelector:@selector(bubbleMenuButtonDidExpand:)]) { 68 | [self.delegate bubbleMenuButtonDidExpand:self]; 69 | } 70 | } 71 | 72 | self.userInteractionEnabled = YES; 73 | }]; 74 | 75 | NSArray *buttonContainer = _buttonContainer; 76 | 77 | if (self.direction == DirectionUp || self.direction == DirectionLeft) { 78 | buttonContainer = [self _reverseOrderFromArray:_buttonContainer]; 79 | } 80 | 81 | for (int i = 0; i < buttonContainer.count; i++) { 82 | int index = (int)buttonContainer.count - (i + 1); 83 | 84 | UIButton *button = [buttonContainer objectAtIndex:index]; 85 | button.hidden = NO; 86 | 87 | // position animation 88 | CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 89 | 90 | CGPoint originPosition = CGPointZero; 91 | CGPoint finalPosition = CGPointZero; 92 | 93 | switch (self.direction) { 94 | case DirectionLeft: 95 | originPosition = CGPointMake(self.frame.size.width - self.homeButtonView.frame.size.width, self.frame.size.height/2.f); 96 | finalPosition = CGPointMake(self.frame.size.width - self.homeButtonView.frame.size.width - button.frame.size.width/2.f - self.buttonSpacing 97 | - ((button.frame.size.width + self.buttonSpacing) * index), 98 | self.frame.size.height/2.f); 99 | break; 100 | 101 | case DirectionRight: 102 | originPosition = CGPointMake(self.homeButtonView.frame.size.width, self.frame.size.height/2.f); 103 | finalPosition = CGPointMake(self.homeButtonView.frame.size.width + self.buttonSpacing + button.frame.size.width/2.f 104 | + ((button.frame.size.width + self.buttonSpacing) * index), 105 | self.frame.size.height/2.f); 106 | break; 107 | 108 | case DirectionUp: 109 | originPosition = CGPointMake(self.frame.size.width/2.f, self.frame.size.height - self.homeButtonView.frame.size.height); 110 | finalPosition = CGPointMake(self.frame.size.width/2.f, 111 | self.frame.size.height - self.homeButtonView.frame.size.height - self.buttonSpacing - button.frame.size.height/2.f 112 | - ((button.frame.size.height + self.buttonSpacing) * index)); 113 | break; 114 | 115 | case DirectionDown: 116 | originPosition = CGPointMake(self.frame.size.width/2.f, self.homeButtonView.frame.size.height); 117 | finalPosition = CGPointMake(self.frame.size.width/2.f, 118 | self.homeButtonView.frame.size.height + self.buttonSpacing + button.frame.size.height/2.f 119 | + ((button.frame.size.height + self.buttonSpacing) * index)); 120 | break; 121 | 122 | default: 123 | break; 124 | } 125 | 126 | positionAnimation.duration = _animationDuration; 127 | positionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 128 | positionAnimation.fromValue = [NSValue valueWithCGPoint:originPosition]; 129 | positionAnimation.toValue = [NSValue valueWithCGPoint:finalPosition]; 130 | positionAnimation.beginTime = CACurrentMediaTime() + (_animationDuration/(float)_buttonContainer.count * (float)i); 131 | positionAnimation.fillMode = kCAFillModeForwards; 132 | positionAnimation.removedOnCompletion = NO; 133 | 134 | [button.layer addAnimation:positionAnimation forKey:@"positionAnimation"]; 135 | 136 | button.layer.position = finalPosition; 137 | 138 | // scale animation 139 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 140 | 141 | scaleAnimation.duration = _animationDuration; 142 | scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 143 | scaleAnimation.fromValue = [NSNumber numberWithFloat:0.01f]; 144 | scaleAnimation.toValue = [NSNumber numberWithFloat:1.f]; 145 | scaleAnimation.beginTime = CACurrentMediaTime() + (_animationDuration/(float)_buttonContainer.count * (float)i) + 0.03f; 146 | scaleAnimation.fillMode = kCAFillModeForwards; 147 | scaleAnimation.removedOnCompletion = NO; 148 | 149 | [button.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"]; 150 | 151 | button.transform = CGAffineTransformMakeScale(0.01f, 0.01f); 152 | } 153 | 154 | [CATransaction commit]; 155 | 156 | _isCollapsed = NO; 157 | } 158 | 159 | - (void)dismissButtons { 160 | if ([self.delegate respondsToSelector:@selector(bubbleMenuButtonWillCollapse:)]) { 161 | [self.delegate bubbleMenuButtonWillCollapse:self]; 162 | } 163 | 164 | self.userInteractionEnabled = NO; 165 | 166 | [CATransaction begin]; 167 | [CATransaction setAnimationDuration:_animationDuration]; 168 | [CATransaction setCompletionBlock:^{ 169 | [self _finishCollapse]; 170 | 171 | for (UIButton *button in _buttonContainer) { 172 | button.transform = CGAffineTransformIdentity; 173 | button.hidden = YES; 174 | } 175 | 176 | if (self.delegate != nil) { 177 | if ([self.delegate respondsToSelector:@selector(bubbleMenuButtonDidCollapse:)]) { 178 | [self.delegate bubbleMenuButtonDidCollapse:self]; 179 | } 180 | } 181 | 182 | self.userInteractionEnabled = YES; 183 | }]; 184 | 185 | int index = 0; 186 | for (int i = (int)_buttonContainer.count - 1; i >= 0; i--) { 187 | UIButton *button = [_buttonContainer objectAtIndex:i]; 188 | 189 | if (self.direction == DirectionDown || self.direction == DirectionRight) { 190 | button = [_buttonContainer objectAtIndex:index]; 191 | } 192 | 193 | // scale animation 194 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 195 | 196 | scaleAnimation.duration = _animationDuration; 197 | scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 198 | scaleAnimation.fromValue = [NSNumber numberWithFloat:1.f]; 199 | scaleAnimation.toValue = [NSNumber numberWithFloat:0.01f]; 200 | scaleAnimation.beginTime = CACurrentMediaTime() + (_animationDuration/(float)_buttonContainer.count * (float)index) + 0.03; 201 | scaleAnimation.fillMode = kCAFillModeForwards; 202 | scaleAnimation.removedOnCompletion = NO; 203 | 204 | [button.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"]; 205 | 206 | button.transform = CGAffineTransformMakeScale(1.f, 1.f); 207 | 208 | // position animation 209 | CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 210 | 211 | CGPoint originPosition = button.layer.position; 212 | CGPoint finalPosition = CGPointZero; 213 | 214 | switch (self.direction) { 215 | case DirectionLeft: 216 | finalPosition = CGPointMake(self.frame.size.width - self.homeButtonView.frame.size.width, self.frame.size.height/2.f); 217 | break; 218 | 219 | case DirectionRight: 220 | finalPosition = CGPointMake(self.homeButtonView.frame.size.width, self.frame.size.height/2.f); 221 | break; 222 | 223 | case DirectionUp: 224 | finalPosition = CGPointMake(self.frame.size.width/2.f, self.frame.size.height - self.homeButtonView.frame.size.height); 225 | break; 226 | 227 | case DirectionDown: 228 | finalPosition = CGPointMake(self.frame.size.width/2.f, self.homeButtonView.frame.size.height); 229 | break; 230 | 231 | default: 232 | break; 233 | } 234 | 235 | positionAnimation.duration = _animationDuration; 236 | positionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 237 | positionAnimation.fromValue = [NSValue valueWithCGPoint:originPosition]; 238 | positionAnimation.toValue = [NSValue valueWithCGPoint:finalPosition]; 239 | positionAnimation.beginTime = CACurrentMediaTime() + (_animationDuration/(float)_buttonContainer.count * (float)index); 240 | positionAnimation.fillMode = kCAFillModeForwards; 241 | positionAnimation.removedOnCompletion = NO; 242 | 243 | [button.layer addAnimation:positionAnimation forKey:@"positionAnimation"]; 244 | 245 | button.layer.position = originPosition; 246 | index++; 247 | } 248 | 249 | [CATransaction commit]; 250 | 251 | _isCollapsed = YES; 252 | } 253 | 254 | #pragma mark - 255 | #pragma mark Private Methods 256 | 257 | - (void)_defaultInit { 258 | self.clipsToBounds = YES; 259 | self.layer.masksToBounds = YES; 260 | 261 | self.direction = DirectionUp; 262 | self.animatedHighlighting = YES; 263 | self.collapseAfterSelection = YES; 264 | self.animationDuration = kDefaultAnimationDuration; 265 | self.standbyAlpha = 1.f; 266 | self.highlightAlpha = 0.45f; 267 | self.originFrame = self.frame; 268 | self.buttonSpacing = 20.f; 269 | _isCollapsed = YES; 270 | 271 | self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleTapGesture:)]; 272 | self.tapGestureRecognizer.cancelsTouchesInView = NO; 273 | self.tapGestureRecognizer.delegate = self; 274 | 275 | [self addGestureRecognizer:self.tapGestureRecognizer]; 276 | } 277 | 278 | - (void)_handleTapGesture:(id)sender { 279 | if (self.tapGestureRecognizer.state == UIGestureRecognizerStateEnded) { 280 | CGPoint touchLocation = [self.tapGestureRecognizer locationOfTouch:0 inView:self]; 281 | 282 | if (_collapseAfterSelection && _isCollapsed == NO && CGRectContainsPoint(self.homeButtonView.frame, touchLocation) == false) { 283 | [self dismissButtons]; 284 | } 285 | } 286 | } 287 | 288 | - (void)_animateWithBlock:(void (^)(void))animationBlock { 289 | [UIView transitionWithView:self 290 | duration:kDefaultAnimationDuration 291 | options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut 292 | animations:animationBlock 293 | completion:NULL]; 294 | } 295 | 296 | - (void)_setTouchHighlighted:(BOOL)highlighted { 297 | float alphaValue = highlighted ? _highlightAlpha : _standbyAlpha; 298 | 299 | if (self.homeButtonView.alpha == alphaValue) 300 | return; 301 | 302 | if (_animatedHighlighting) { 303 | [self _animateWithBlock:^{ 304 | if (self.homeButtonView != nil) { 305 | self.homeButtonView.alpha = alphaValue; 306 | } 307 | }]; 308 | } else { 309 | if (self.homeButtonView != nil) { 310 | self.homeButtonView.alpha = alphaValue; 311 | } 312 | } 313 | } 314 | 315 | - (float)_combinedButtonHeight { 316 | float height = 0; 317 | for (UIButton *button in _buttonContainer) { 318 | height += button.frame.size.height + self.buttonSpacing; 319 | } 320 | 321 | return height; 322 | } 323 | 324 | - (float)_combinedButtonWidth { 325 | float width = 0; 326 | for (UIButton *button in _buttonContainer) { 327 | width += button.frame.size.width + self.buttonSpacing; 328 | } 329 | 330 | return width; 331 | } 332 | 333 | /** 334 | * 设置展开后的self.frame 335 | */ 336 | - (void)_prepareForButtonExpansion { 337 | float buttonHeight = [self _combinedButtonHeight]; 338 | float buttonWidth = [self _combinedButtonWidth]; 339 | 340 | switch (self.direction) { 341 | case DirectionUp: 342 | { 343 | self.homeButtonView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;//自动调整与superView顶部的距离,保证与superView底部的距离不变。 344 | 345 | CGRect frame = self.frame; 346 | frame.origin.y -= buttonHeight; 347 | frame.size.height += buttonHeight; 348 | self.frame = frame; 349 | } 350 | break; 351 | 352 | case DirectionDown: 353 | { 354 | self.homeButtonView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin;//自动调整与superView底部的距离,也就是说,与superView顶部的距离不变。 355 | 356 | CGRect frame = self.frame; 357 | frame.size.height += buttonHeight; 358 | self.frame = frame; 359 | } 360 | break; 361 | 362 | case DirectionLeft: 363 | { 364 | self.homeButtonView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;//自动调整与superView左边的距离,保证与superView右边的距离不变。 365 | 366 | CGRect frame = self.frame; 367 | frame.origin.x -= buttonWidth; 368 | frame.size.width += buttonWidth; 369 | self.frame = frame; 370 | } 371 | break; 372 | 373 | case DirectionRight: 374 | { 375 | self.homeButtonView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;//自动调整与superView的右边距离,保证与superView左边的距离不变。 376 | 377 | CGRect frame = self.frame; 378 | frame.size.width += buttonWidth; 379 | self.frame = frame; 380 | } 381 | break; 382 | 383 | default: 384 | break; 385 | } 386 | } 387 | 388 | - (void)_finishCollapse { 389 | self.frame = _originFrame; 390 | } 391 | 392 | - (UIView *)_subviewForPoint:(CGPoint)point { 393 | for (UIView *subview in self.subviews) { 394 | if (CGRectContainsPoint(subview.frame, point)) { 395 | return subview; 396 | } 397 | } 398 | 399 | return self; 400 | } 401 | 402 | - (NSArray *)_reverseOrderFromArray:(NSArray *)array { 403 | NSMutableArray *reverseArray = [NSMutableArray array]; 404 | 405 | for (int i = (int)array.count - 1; i >= 0; i--) { 406 | [reverseArray addObject:[array objectAtIndex:i]]; 407 | } 408 | 409 | return reverseArray; 410 | } 411 | 412 | #pragma mark - 413 | #pragma mark Setters/Getters 414 | 415 | - (void)setHomeButtonView:(UIView *)homeButtonView { 416 | if (_homeButtonView != homeButtonView) { 417 | _homeButtonView = homeButtonView; 418 | } 419 | 420 | if ([_homeButtonView isDescendantOfView:self] == NO) { 421 | [self addSubview:_homeButtonView]; 422 | } 423 | } 424 | 425 | - (NSArray *)buttons { 426 | return [_buttonContainer copy]; 427 | } 428 | 429 | #pragma mark - 430 | #pragma mark Touch Handling Methods 431 | 432 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 433 | [super touchesBegan:touches withEvent:event]; 434 | UITouch *touch = [touches anyObject]; 435 | 436 | if (CGRectContainsPoint(self.homeButtonView.frame, [touch locationInView:self])) { 437 | [self _setTouchHighlighted:YES]; 438 | } 439 | } 440 | 441 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 442 | [super touchesEnded:touches withEvent:event]; 443 | UITouch *touch = [touches anyObject]; 444 | 445 | [self _setTouchHighlighted:NO]; 446 | 447 | if (CGRectContainsPoint(self.homeButtonView.frame, [touch locationInView:self])) { 448 | if (_isCollapsed) { 449 | [self showButtons]; 450 | } else { 451 | [self dismissButtons]; 452 | } 453 | } 454 | } 455 | 456 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 457 | [super touchesCancelled:touches withEvent:event]; 458 | 459 | [self _setTouchHighlighted:NO]; 460 | } 461 | 462 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 463 | [super touchesMoved:touches withEvent:event]; 464 | UITouch *touch = [touches anyObject]; 465 | 466 | [self _setTouchHighlighted:CGRectContainsPoint(self.homeButtonView.frame, [touch locationInView:self])]; 467 | } 468 | 469 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 470 | { 471 | UIView *hitView = [super hitTest:point withEvent:event]; 472 | 473 | if (hitView == self) { 474 | if (_isCollapsed) { 475 | return self; 476 | } else { 477 | return [self _subviewForPoint:point]; 478 | } 479 | } 480 | 481 | return hitView; 482 | } 483 | 484 | #pragma mark - 485 | #pragma mark UIGestureRecognizer Delegate 486 | 487 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 488 | shouldReceiveTouch:(UITouch *)touch { 489 | CGPoint touchLocation = [touch locationInView:self]; 490 | 491 | if ([self _subviewForPoint:touchLocation] != self && _collapseAfterSelection) { 492 | return YES; 493 | } 494 | 495 | return NO; 496 | } 497 | 498 | #pragma mark - 499 | #pragma mark Lifecycle 500 | 501 | - (id)initWithFrame:(CGRect)frame { 502 | self = [super initWithFrame:frame]; 503 | 504 | if (self) { 505 | [self _defaultInit]; 506 | } 507 | return self; 508 | } 509 | 510 | - (id)initWithFrame:(CGRect)frame expansionDirection:(ExpansionDirection)direction { 511 | self = [super initWithFrame:frame]; 512 | 513 | if (self) { 514 | [self _defaultInit]; 515 | _direction = direction; 516 | } 517 | return self; 518 | } 519 | 520 | @end 521 | 522 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/BaseAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // BaseAnimationViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "BaseViewController.h" 12 | 13 | 14 | @interface BaseAnimationViewController : BaseViewController 15 | 16 | -(instancetype)initWithType:(BaseAniType)type; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/BaseAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // BaseAnimationViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "BaseAnimationViewController.h" 12 | 13 | @interface BaseAnimationViewController () 14 | @property(nonatomic,assign)BaseAniType aniType; 15 | @end 16 | 17 | @implementation BaseAnimationViewController 18 | 19 | -(instancetype)initWithType:(BaseAniType)type{ 20 | self = [super init]; 21 | if (self){ 22 | self.aniType = type; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view. 30 | 31 | 32 | NSArray *array_1 = [NSArray arrayWithObjects:@"位移",@"透明度",@"缩放",@"旋转",@"背景色", nil]; 33 | self.navigationItem.title = array_1[self.aniType]; 34 | 35 | } 36 | 37 | -(void)btnClicked:(UIButton *)btn{ 38 | [super btnClicked:btn]; 39 | switch (self.aniType) { 40 | case position: 41 | [self makePositionAnimation]; 42 | break; 43 | case opacity: 44 | [self makeOpacityAnimation]; 45 | break; 46 | case scale: 47 | [self makeScaleAnimation]; 48 | break; 49 | case rotate: 50 | [self makeRotateAnimation]; 51 | break; 52 | case background: 53 | [self makeBackgroundAnimation]; 54 | break; 55 | default: 56 | break; 57 | } 58 | } 59 | 60 | //位移 61 | -(void)makePositionAnimation{ 62 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; 63 | animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2-75)]; 64 | animation.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH-50, SCREEN_HEIGHT/2-75)]; 65 | animation.duration = 1.0f; 66 | //animation.fillMode = kCAFillModeForwards; 67 | //animation.removedOnCompletion = NO; 68 | [self.babyView.layer addAnimation:animation forKey:@"positionAnimation"]; 69 | } 70 | 71 | //透明度 72 | -(void)makeOpacityAnimation{ 73 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 74 | animation.fromValue = [NSNumber numberWithFloat:1.0f]; 75 | animation.toValue = [NSNumber numberWithFloat:0.5f]; 76 | animation.duration = 1.0f; 77 | [self.babyView.layer addAnimation:animation forKey:@"opacityAnimation"]; 78 | } 79 | 80 | //缩放 81 | -(void)makeScaleAnimation{ 82 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 83 | animation.toValue = [NSNumber numberWithFloat:2.0f]; 84 | animation.duration = 1.0f; 85 | [self.babyView.layer addAnimation:animation forKey:@"scaleAnimation"]; 86 | } 87 | 88 | //旋转 89 | -(void)makeRotateAnimation{ 90 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 91 | animation.toValue = [NSNumber numberWithFloat:M_PI]; 92 | animation.duration = 1.0f; 93 | [self.babyView.layer addAnimation:animation forKey:@"rotateAnimation"]; 94 | } 95 | 96 | //背景色变化 97 | -(void)makeBackgroundAnimation{ 98 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"]; 99 | animation.toValue = (id)[UIColor greenColor].CGColor; 100 | animation.duration = 1.0f; 101 | [self.babyView.layer addAnimation:animation forKey:@"backgroundAnimation"]; 102 | } 103 | 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // BaseViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | #define SCREEN_WIDTH self.view.frame.size.width 14 | #define SCREEN_HEIGHT self.view.frame.size.height 15 | 16 | typedef NS_ENUM(NSInteger, BaseAniType){ 17 | position = 0, 18 | opacity, 19 | scale, 20 | rotate, 21 | background 22 | }; 23 | 24 | typedef NS_ENUM(NSInteger, KeyAniType){ 25 | keyFrame = 0, 26 | path, 27 | shake 28 | }; 29 | 30 | typedef NS_ENUM(NSInteger, GroupAniType){ 31 | sameTime = 0, 32 | goOn 33 | }; 34 | 35 | typedef NS_ENUM(NSInteger, TransitionAniType){ 36 | fade = 0, 37 | moveIn, 38 | push, 39 | reveal, 40 | cube, 41 | suck, 42 | oglFile, 43 | ripple, 44 | curl, 45 | unCurl, 46 | caOpen, 47 | caClose 48 | }; 49 | 50 | @interface BaseViewController : UIViewController 51 | 52 | @property(nonatomic,strong)UIView *babyView; 53 | 54 | -(void)btnClicked:(UIButton *)btn; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // BaseViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "BaseViewController.h" 12 | 13 | @interface BaseViewController () 14 | 15 | @end 16 | 17 | @implementation BaseViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view. 22 | 23 | self.view.backgroundColor = [UIColor whiteColor]; 24 | 25 | self.babyView = [[UIView alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-100)/2, SCREEN_HEIGHT/2-100,100 ,100)]; 26 | self.babyView.backgroundColor = [UIColor redColor]; 27 | [self.view addSubview:self.babyView]; 28 | 29 | UIButton *startBtn = [[UIButton alloc] initWithFrame:CGRectMake((SCREEN_WIDTH-60)/2, SCREEN_HEIGHT-80, 60, 30)]; 30 | [startBtn setTitle:@"开始" forState:UIControlStateNormal]; 31 | startBtn.backgroundColor = [UIColor grayColor]; 32 | [startBtn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; 33 | [self.view addSubview:startBtn]; 34 | 35 | } 36 | 37 | -(void)btnClicked:(UIButton *)btn{ 38 | 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/CombinationAniViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // CombinationAniViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | #define SCREEN_WIDTH self.view.frame.size.width 14 | #define SCREEN_HEIGHT self.view.frame.size.height 15 | 16 | typedef NS_ENUM(NSInteger, CombinationAniType){ 17 | aPath = 0, 18 | dingding, 19 | dianzan, 20 | bezier, 21 | }; 22 | 23 | @interface CombinationAniViewController : UIViewController 24 | 25 | -(instancetype)initWithType:(CombinationAniType)type; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/CombinationAniViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // CombinationAniViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "CombinationAniViewController.h" 12 | #import "DCPathButton.h" 13 | #import "DWBubbleMenuButton.h" 14 | #import "MCFireworksButton.h" 15 | #import "GJProgressAniView.h" 16 | 17 | @interface CombinationAniViewController () 18 | @property(nonatomic,assign)CombinationAniType aniType; 19 | @end 20 | 21 | @implementation CombinationAniViewController 22 | -(instancetype)initWithType:(CombinationAniType)type{ 23 | self = [super init]; 24 | if (self){ 25 | self.aniType = type; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)viewDidLoad { 31 | [super viewDidLoad]; 32 | // Do any additional setup after loading the view. 33 | 34 | self.view.backgroundColor = [UIColor whiteColor]; 35 | 36 | NSArray *array_5 = [NSArray arrayWithObjects:@"path",@"钉钉",@"点赞",@"贝塞尔曲线",@"进度", nil]; 37 | self.navigationItem.title = array_5[self.aniType]; 38 | 39 | [self loadAnimationWithType:self.aniType]; 40 | } 41 | 42 | -(void)loadAnimationWithType:(NSInteger)type{ 43 | switch (type) { 44 | case 0: 45 | [self makeAPathAnimation]; 46 | break; 47 | case 1: 48 | [self makeDingdingAnimation]; 49 | break; 50 | case 2: 51 | [self makeDianzanAnimation]; 52 | break; 53 | case 3: 54 | [self makeBezierPathAnimation]; 55 | break; 56 | case 4: 57 | [self makeProgressAnimation]; 58 | break; 59 | default: 60 | break; 61 | } 62 | } 63 | 64 | -(void)makeAPathAnimation{ 65 | // Configure center button 66 | // 67 | DCPathButton *dcPathButton = [[DCPathButton alloc]initWithCenterImage:[UIImage imageNamed:@"chooser-button-tab"] 68 | hilightedImage:[UIImage imageNamed:@"chooser-button-tab-highlighted"]]; 69 | 70 | dcPathButton.delegate = self; 71 | 72 | // Configure item buttons 73 | // 74 | DCPathItemButton *itemButton_1 = [[DCPathItemButton alloc]initWithImage:[UIImage imageNamed:@"chooser-moment-icon-music"] 75 | highlightedImage:[UIImage imageNamed:@"chooser-moment-icon-music-highlighted"] 76 | backgroundImage:[UIImage imageNamed:@"chooser-moment-button"] 77 | backgroundHighlightedImage:[UIImage imageNamed:@"chooser-moment-button-highlighted"]]; 78 | 79 | DCPathItemButton *itemButton_2 = [[DCPathItemButton alloc]initWithImage:[UIImage imageNamed:@"chooser-moment-icon-place"] 80 | highlightedImage:[UIImage imageNamed:@"chooser-moment-icon-place-highlighted"] 81 | backgroundImage:[UIImage imageNamed:@"chooser-moment-button"] 82 | backgroundHighlightedImage:[UIImage imageNamed:@"chooser-moment-button-highlighted"]]; 83 | 84 | DCPathItemButton *itemButton_3 = [[DCPathItemButton alloc]initWithImage:[UIImage imageNamed:@"chooser-moment-icon-camera"] 85 | highlightedImage:[UIImage imageNamed:@"chooser-moment-icon-camera-highlighted"] 86 | backgroundImage:[UIImage imageNamed:@"chooser-moment-button"] 87 | backgroundHighlightedImage:[UIImage imageNamed:@"chooser-moment-button-highlighted"]]; 88 | 89 | DCPathItemButton *itemButton_4 = [[DCPathItemButton alloc]initWithImage:[UIImage imageNamed:@"chooser-moment-icon-thought"] 90 | highlightedImage:[UIImage imageNamed:@"chooser-moment-icon-thought-highlighted"] 91 | backgroundImage:[UIImage imageNamed:@"chooser-moment-button"] 92 | backgroundHighlightedImage:[UIImage imageNamed:@"chooser-moment-button-highlighted"]]; 93 | 94 | DCPathItemButton *itemButton_5 = [[DCPathItemButton alloc]initWithImage:[UIImage imageNamed:@"chooser-moment-icon-sleep"] 95 | highlightedImage:[UIImage imageNamed:@"chooser-moment-icon-sleep-highlighted"] 96 | backgroundImage:[UIImage imageNamed:@"chooser-moment-button"] 97 | backgroundHighlightedImage:[UIImage imageNamed:@"chooser-moment-button-highlighted"]]; 98 | 99 | // Add the item button into the center button 100 | // 101 | [dcPathButton addPathItems:@[itemButton_1, itemButton_2, itemButton_3, itemButton_4, itemButton_5]]; 102 | 103 | [self.view addSubview:dcPathButton]; 104 | 105 | } 106 | 107 | -(void)itemButtonTappedAtIndex:(NSUInteger)index{ 108 | NSLog(@"you did click btn in %ld",index); 109 | } 110 | 111 | //=================================================================================================================== 112 | 113 | -(void)makeDingdingAnimation{ 114 | UILabel *homeLabel = [self createHomeButtonView]; 115 | 116 | DWBubbleMenuButton *upMenuView = [[DWBubbleMenuButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width - homeLabel.frame.size.width - 20.f, 117 | self.view.frame.size.height - homeLabel.frame.size.height - 20.f, 118 | homeLabel.frame.size.width, 119 | homeLabel.frame.size.height) 120 | expansionDirection:DirectionUp]; 121 | upMenuView.homeButtonView = homeLabel; 122 | [upMenuView addButtons:[self createDemoButtonArray]]; 123 | 124 | [self.view addSubview:upMenuView]; 125 | } 126 | 127 | - (UILabel *)createHomeButtonView { 128 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.f, 0.f, 40.f, 40.f)]; 129 | 130 | label.text = @"Tap"; 131 | label.textColor = [UIColor whiteColor]; 132 | label.textAlignment = NSTextAlignmentCenter; 133 | label.layer.cornerRadius = label.frame.size.height / 2.f; 134 | label.backgroundColor =[UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.5f]; 135 | label.clipsToBounds = YES; 136 | 137 | return label; 138 | } 139 | 140 | - (NSArray *)createDemoButtonArray { 141 | NSMutableArray *buttonsMutable = [[NSMutableArray alloc] init]; 142 | 143 | int i = 0; 144 | for (NSString *title in @[@"A", @"B", @"C", @"D", @"E", @"F"]) { 145 | UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; 146 | 147 | [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 148 | [button setTitle:title forState:UIControlStateNormal]; 149 | 150 | button.frame = CGRectMake(0.f, 0.f, 30.f, 30.f); 151 | button.layer.cornerRadius = button.frame.size.height / 2.f; 152 | button.backgroundColor = [UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.5f]; 153 | button.clipsToBounds = YES; 154 | button.tag = i++; 155 | 156 | [button addTarget:self action:@selector(dwBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 157 | 158 | [buttonsMutable addObject:button]; 159 | } 160 | 161 | return [buttonsMutable copy]; 162 | } 163 | 164 | - (void)dwBtnClick:(UIButton *)sender { 165 | NSLog(@"DWButton tapped, tag: %ld", (long)sender.tag); 166 | } 167 | 168 | //=================================================================================================================== 169 | 170 | -(void)makeDianzanAnimation{ 171 | MCFireworksButton *btn = [[MCFireworksButton alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT/2-25, 50, 50)]; 172 | btn.particleImage = [UIImage imageNamed:@"Sparkle"]; 173 | btn.particleScale = 0.05; 174 | btn.particleScaleRange = 0.02; 175 | btn.selected = NO; 176 | [btn setImage:[UIImage imageNamed:@"Like"] forState:UIControlStateNormal]; 177 | 178 | [btn addTarget:self action:@selector(handleButtonPress:) forControlEvents:UIControlEventTouchUpInside]; 179 | [self.view addSubview:btn]; 180 | } 181 | 182 | -(void)handleButtonPress:(MCFireworksButton *)btn{ 183 | btn.selected = !btn.selected; 184 | if (btn.selected){ 185 | [btn popOutsideWithDuration:0.5]; 186 | [btn setImage:[UIImage imageNamed:@"Like-Blue"] forState:UIControlStateNormal]; 187 | [btn animate]; 188 | }else{ 189 | [btn popInsideWithDuration:0.4]; 190 | [btn setImage:[UIImage imageNamed:@"Like"] forState:UIControlStateNormal]; 191 | } 192 | } 193 | 194 | //=================================================================================================================== 195 | - (void)makeBezierPathAnimation{ 196 | 197 | UIBezierPath *path = [UIBezierPath bezierPath]; 198 | // 首先设置一个起始点 199 | CGPoint startPoint = CGPointMake(self.view.frame.size.width/2, 120); 200 | // 以起始点为路径的起点 201 | [path moveToPoint:CGPointMake(self.view.frame.size.width/2, 120)]; 202 | // 设置一个终点 203 | CGPoint endPoint = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height-400); 204 | // 设置第一个控制点 205 | CGPoint controlPoint1 = CGPointMake(100, 20); 206 | // 设置第二个控制点 207 | CGPoint controlPoint2 = CGPointMake(0, 180); 208 | // 添加二次贝塞尔曲线 209 | [path addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; 210 | // 设置另一个起始点 211 | [path moveToPoint:endPoint]; 212 | // 设置第三个控制点 213 | CGPoint controlPoint3 = CGPointMake(self.view.frame.size.width, 180); 214 | // 设置第四个控制点 215 | CGPoint controlPoint4 = CGPointMake(self.view.frame.size.width-100, 20); 216 | // 添加二次贝塞尔曲线 217 | [path addCurveToPoint:startPoint controlPoint1:controlPoint3 controlPoint2:controlPoint4]; 218 | // 设置线断面类型 219 | path.lineCapStyle = kCGLineCapRound; 220 | // 设置连接类型 221 | path.lineJoinStyle = kCGLineJoinRound; 222 | 223 | CAShapeLayer *animLayer = [CAShapeLayer layer]; 224 | animLayer.path = path.CGPath; 225 | animLayer.lineWidth = 2.f; 226 | animLayer.strokeColor = [UIColor blackColor].CGColor; 227 | animLayer.fillColor = [UIColor clearColor].CGColor; 228 | animLayer.strokeStart = 0; 229 | animLayer.strokeEnd = 1.; 230 | [self.view.layer addSublayer:animLayer]; 231 | 232 | 233 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 234 | animation.fromValue = @(0); 235 | animation.toValue = @(1.f); 236 | animation.duration = 2.0f; 237 | animation.removedOnCompletion = NO; 238 | animation.fillMode = kCAFillModeForwards; 239 | [animLayer addAnimation:animation forKey:@"strokeEnd"]; 240 | 241 | } 242 | 243 | //=================================================================================================================== 244 | - (void)makeProgressAnimation{ 245 | UIView *backView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 300)]; 246 | backView.backgroundColor = [UIColor redColor]; 247 | [self.view addSubview:backView]; 248 | 249 | GJProgressAniView *proView = [[GJProgressAniView alloc] initWithFrame:CGRectMake((backView.frame.size.width-115)/2, (300-115)/2, 115, 115)]; 250 | proView.mainPathWidth = 17; 251 | [backView addSubview:proView]; 252 | 253 | [proView drawCircleWithProgress:70]; 254 | } 255 | 256 | @end 257 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/GroupAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // GroupAnimationViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "BaseViewController.h" 12 | 13 | @interface GroupAnimationViewController : BaseViewController 14 | 15 | -(instancetype)initWithType:(GroupAniType)type; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/GroupAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // GroupAnimationViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "GroupAnimationViewController.h" 12 | 13 | @interface GroupAnimationViewController () 14 | @property(nonatomic,assign)GroupAniType aniType; 15 | @end 16 | 17 | @implementation GroupAnimationViewController 18 | 19 | -(instancetype)initWithType:(GroupAniType)type{ 20 | self = [super init]; 21 | if (self){ 22 | self.aniType = type; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view. 30 | 31 | NSArray *array_3 = [NSArray arrayWithObjects:@"同时",@"连续", nil]; 32 | self.navigationItem.title = array_3[self.aniType]; 33 | 34 | } 35 | 36 | -(void)btnClicked:(UIButton *)btn{ 37 | [super btnClicked:btn]; 38 | switch (self.aniType) { 39 | case keyFrame: 40 | [self makeSameTimeAnimation]; 41 | break; 42 | case path: 43 | [self makeGoOnAnimation]; 44 | break; 45 | default: 46 | break; 47 | } 48 | } 49 | 50 | -(void)makeSameTimeAnimation{ 51 | CAKeyframeAnimation *positionAni = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 52 | NSValue *value_0 = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2-50)]; 53 | NSValue *value_1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)]; 54 | NSValue *value_2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)]; 55 | NSValue *value_3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)]; 56 | NSValue *value_4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)]; 57 | NSValue *value_5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH-50, SCREEN_HEIGHT/2-50)]; 58 | positionAni.values = [NSArray arrayWithObjects:value_0,value_1,value_2,value_3,value_4,value_5, nil]; 59 | 60 | CABasicAnimation *scaleAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 61 | scaleAni.fromValue = [NSNumber numberWithFloat:0.8f]; 62 | scaleAni.toValue = [NSNumber numberWithFloat:2.0f]; 63 | 64 | CABasicAnimation *rotateAni = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; 65 | rotateAni.toValue = [NSNumber numberWithFloat:M_PI*4]; 66 | 67 | CAAnimationGroup *groupAni = [CAAnimationGroup animation]; 68 | groupAni.animations = [NSArray arrayWithObjects:positionAni,scaleAni,rotateAni, nil]; 69 | groupAni.duration = 4.0f; 70 | [self.babyView.layer addAnimation:groupAni forKey:@"groupAnimation"]; 71 | } 72 | 73 | //连续动画要处理好时间的衔接 74 | -(void)makeGoOnAnimation{ 75 | //定义一个动画开始的时间 76 | CFTimeInterval currentTime = CACurrentMediaTime(); 77 | 78 | CABasicAnimation *positionAni = [CABasicAnimation animationWithKeyPath:@"position"]; 79 | positionAni.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2)]; 80 | positionAni.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)]; 81 | positionAni.duration = 1.0f; 82 | positionAni.fillMode = kCAFillModeForwards; 83 | positionAni.removedOnCompletion = NO; 84 | positionAni.beginTime = currentTime; 85 | [self.babyView.layer addAnimation:positionAni forKey:@"positionAnimation"]; 86 | 87 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 88 | scaleAnimation.fromValue = [NSNumber numberWithFloat:0.8f]; 89 | scaleAnimation.toValue = [NSNumber numberWithFloat:2.0f]; 90 | scaleAnimation.duration = 1.0f; 91 | scaleAnimation.fillMode = kCAFillModeForwards; 92 | scaleAnimation.removedOnCompletion = NO; 93 | scaleAnimation.beginTime = currentTime + 1.0f; 94 | [self.babyView.layer addAnimation:scaleAnimation forKey:@"scaleAnimation"]; 95 | 96 | CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; 97 | rotateAnimation.toValue = [NSNumber numberWithFloat:M_PI*4]; 98 | rotateAnimation.duration = 1.0f; 99 | rotateAnimation.fillMode = kCAFillModeForwards; 100 | rotateAnimation.removedOnCompletion = NO; 101 | rotateAnimation.beginTime = currentTime + 2.0f; 102 | [self.babyView.layer addAnimation:rotateAnimation forKey:@"rotateAnimation"]; 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/KeyFrameAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // KeyFrameAnimationViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "BaseViewController.h" 12 | 13 | 14 | @interface KeyFrameAnimationViewController : BaseViewController 15 | 16 | -(instancetype)initWithType:(KeyAniType)type; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/KeyFrameAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // KeyFrameAnimationViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "KeyFrameAnimationViewController.h" 12 | 13 | @interface KeyFrameAnimationViewController () 14 | @property(nonatomic,assign)KeyAniType aniType; 15 | @end 16 | 17 | @implementation KeyFrameAnimationViewController 18 | 19 | -(instancetype)initWithType:(KeyAniType)type{ 20 | self = [super init]; 21 | if (self){ 22 | self.aniType = type; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view. 30 | 31 | 32 | NSArray *array_2 = [NSArray arrayWithObjects:@"关键帧",@"路径",@"抖动", nil]; 33 | self.navigationItem.title = array_2[self.aniType]; 34 | 35 | } 36 | 37 | -(void)btnClicked:(UIButton *)btn{ 38 | [super btnClicked:btn]; 39 | switch (self.aniType) { 40 | case keyFrame: 41 | [self makeKeyFrameAnimation]; 42 | break; 43 | case path: 44 | [self makePathAnimation]; 45 | break; 46 | case shake: 47 | [self makeShakeAnimation]; 48 | break; 49 | default: 50 | break; 51 | } 52 | } 53 | 54 | //关键帧动画 55 | -(void)makeKeyFrameAnimation{ 56 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 57 | NSValue *value_0 = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2-50)]; 58 | NSValue *value_1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)]; 59 | NSValue *value_2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)]; 60 | NSValue *value_3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)]; 61 | NSValue *value_4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)]; 62 | NSValue *value_5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH-50, SCREEN_HEIGHT/2-50)]; 63 | animation.values = [NSArray arrayWithObjects:value_0,value_1,value_2,value_3,value_4,value_5, nil]; 64 | animation.duration = 2.0f; 65 | [self.babyView.layer addAnimation:animation forKey:@"keyFrameAnimation"]; 66 | } 67 | 68 | //路径 69 | -(void)makePathAnimation{ 70 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 71 | UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2) radius:60 startAngle:0.0f endAngle:M_PI*2 clockwise:YES]; 72 | animation.duration = 2.0f; 73 | animation.path = path.CGPath; 74 | [self.babyView.layer addAnimation:animation forKey:@"pathAnimation"]; 75 | } 76 | 77 | //抖动动画 78 | -(void)makeShakeAnimation{ 79 | CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"]; 80 | NSValue *value_0 = [NSNumber numberWithFloat:-M_PI/180*4]; 81 | NSValue *value_1 = [NSNumber numberWithFloat:M_PI/180*4]; 82 | NSValue *value_3 = [NSNumber numberWithFloat:-M_PI/180*4]; 83 | anima.values = @[value_0,value_1,value_3]; 84 | anima.repeatCount = MAXFLOAT; 85 | [self.babyView.layer addAnimation:anima forKey:@"shakeAnimation"]; 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/TransitionAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // TransitionAnimationViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "BaseViewController.h" 12 | 13 | @interface TransitionAnimationViewController : BaseViewController 14 | 15 | -(instancetype)initWithType:(TransitionAniType)type; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/GJAnimationViewControllers/TransitionAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // TransitionAnimationViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "TransitionAnimationViewController.h" 12 | 13 | @interface TransitionAnimationViewController () 14 | @property(nonatomic,strong)UILabel *numLabel; 15 | @property(nonatomic,assign)NSInteger index; 16 | @property(nonatomic,assign)TransitionAniType aniType; 17 | @end 18 | 19 | @implementation TransitionAnimationViewController 20 | 21 | -(instancetype)initWithType:(TransitionAniType)type{ 22 | self = [super init]; 23 | if (self){ 24 | self.aniType = type; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | // Do any additional setup after loading the view. 32 | 33 | NSArray *array_4 = [NSArray arrayWithObjects:@"fade",@"moveIn",@"push",@"reveal",@"cube",@"suck",@"oglFile",@"ripple",@"curl",@"unCurl",@"caOpen",@"caClose", nil]; 34 | self.navigationItem.title = array_4[self.aniType]; 35 | 36 | _index = 0; 37 | 38 | self.numLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.babyView.frame)/2-12.5, CGRectGetHeight(self.babyView.frame)/2-20, 25, 40)]; 39 | self.numLabel.textAlignment = NSTextAlignmentCenter; 40 | self.numLabel.font = [UIFont systemFontOfSize:40]; 41 | [self.babyView addSubview:self.numLabel]; 42 | 43 | [self addNumToLabel]; 44 | } 45 | 46 | -(void)addNumToLabel{ 47 | if (_index > 3){ 48 | _index = 0; 49 | } 50 | 51 | NSArray *colors = [NSArray arrayWithObjects:[UIColor cyanColor],[UIColor magentaColor],[UIColor greenColor],[UIColor purpleColor], nil]; 52 | NSArray *numArray = @[@"1",@"2",@"3",@"4"]; 53 | 54 | self.babyView.backgroundColor = colors[_index]; 55 | self.numLabel.text = numArray[_index]; 56 | 57 | _index++; 58 | } 59 | 60 | -(void)btnClicked:(UIButton *)btn{ 61 | [super btnClicked:btn]; 62 | switch (self.aniType) { 63 | case fade: 64 | [self fade]; 65 | break; 66 | case moveIn: 67 | [self moveIn]; 68 | break; 69 | case push: 70 | [self push]; 71 | break; 72 | case reveal: 73 | [self reveal]; 74 | break; 75 | case cube: 76 | [self cube]; 77 | break; 78 | case suck: 79 | [self suck]; 80 | break; 81 | case oglFile: 82 | [self oglFile]; 83 | break; 84 | case ripple: 85 | [self ripple]; 86 | break; 87 | case curl: 88 | [self curl]; 89 | break; 90 | case unCurl: 91 | [self unCurl]; 92 | break; 93 | case caOpen: 94 | [self caOpen]; 95 | break; 96 | case caClose: 97 | [self caClose]; 98 | break; 99 | default: 100 | break; 101 | } 102 | } 103 | 104 | -(void)fade{ 105 | [self addNumToLabel]; 106 | 107 | CATransition *transitionAni = [CATransition animation]; 108 | transitionAni.type = kCATransitionFade; 109 | transitionAni.duration = 1.0f; 110 | [self.babyView.layer addAnimation:transitionAni forKey:@"fadeAnimation"]; 111 | } 112 | 113 | -(void)moveIn{ 114 | [self addNumToLabel]; 115 | 116 | CATransition *transitionAni = [CATransition animation]; 117 | transitionAni.type = kCATransitionMoveIn; 118 | transitionAni.subtype = kCATransitionFromRight; 119 | transitionAni.duration = 1.0f; 120 | [self.babyView.layer addAnimation:transitionAni forKey:@"moveInAnimation"]; 121 | } 122 | 123 | -(void)push{ 124 | [self addNumToLabel]; 125 | 126 | CATransition *transitionAni = [CATransition animation]; 127 | transitionAni.type = kCATransitionPush; 128 | transitionAni.subtype = kCATransitionFromRight; 129 | transitionAni.duration = 1.0f; 130 | [self.babyView.layer addAnimation:transitionAni forKey:@"pushAnimation"]; 131 | } 132 | 133 | -(void)reveal{ 134 | [self addNumToLabel]; 135 | 136 | CATransition *transitionAni = [CATransition animation]; 137 | transitionAni.type = kCATransitionReveal; 138 | transitionAni.subtype = kCATransitionFromRight; 139 | transitionAni.duration = 1.0f; 140 | [self.babyView.layer addAnimation:transitionAni forKey:@"revealAnimation"]; 141 | } 142 | 143 | -(void)cube{ 144 | [self addNumToLabel]; 145 | 146 | CATransition *transitionAni = [CATransition animation]; 147 | transitionAni.type = @"cube"; 148 | transitionAni.subtype = kCATransitionFromRight; 149 | transitionAni.duration = 1.0f; 150 | [self.babyView.layer addAnimation:transitionAni forKey:@"cubeAnimation"]; 151 | } 152 | 153 | -(void)suck{ 154 | [self addNumToLabel]; 155 | 156 | CATransition *transitionAni = [CATransition animation]; 157 | transitionAni.type = @"suckEffect"; 158 | transitionAni.subtype = kCATransitionFromRight; 159 | transitionAni.duration = 1.0f; 160 | [self.babyView.layer addAnimation:transitionAni forKey:@"suckAnimation"]; 161 | } 162 | 163 | -(void)oglFile{ 164 | [self addNumToLabel]; 165 | 166 | CATransition *transitionAni = [CATransition animation]; 167 | transitionAni.type = @"oglFlip"; 168 | transitionAni.subtype = kCATransitionFromRight; 169 | transitionAni.duration = 1.0f; 170 | [self.babyView.layer addAnimation:transitionAni forKey:@"oglFileAnimation"]; 171 | } 172 | 173 | -(void)ripple{ 174 | [self addNumToLabel]; 175 | 176 | CATransition *transitionAni = [CATransition animation]; 177 | transitionAni.type = @"rippleEffect"; 178 | transitionAni.subtype = kCATransitionFromRight; 179 | transitionAni.duration = 1.0f; 180 | [self.babyView.layer addAnimation:transitionAni forKey:@"rippleAnimation"]; 181 | } 182 | 183 | -(void)curl{ 184 | [self addNumToLabel]; 185 | 186 | CATransition *transitionAni = [CATransition animation]; 187 | transitionAni.type = @"pageCurl"; 188 | transitionAni.subtype = kCATransitionFromRight; 189 | transitionAni.duration = 1.0f; 190 | [self.babyView.layer addAnimation:transitionAni forKey:@"curlAnimation"]; 191 | } 192 | 193 | -(void)unCurl{ 194 | [self addNumToLabel]; 195 | 196 | CATransition *transitionAni = [CATransition animation]; 197 | transitionAni.type = @"pageUnCurl"; 198 | transitionAni.subtype = kCATransitionFromRight; 199 | transitionAni.duration = 1.0f; 200 | [self.babyView.layer addAnimation:transitionAni forKey:@"unCurlAnimation"]; 201 | } 202 | 203 | -(void)caOpen{ 204 | [self addNumToLabel]; 205 | 206 | CATransition *transitionAni = [CATransition animation]; 207 | transitionAni.type = @"cameraIrisHollowOpen"; 208 | transitionAni.subtype = kCATransitionFromRight; 209 | transitionAni.duration = 1.0f; 210 | [self.babyView.layer addAnimation:transitionAni forKey:@"caOpenAnimation"]; 211 | } 212 | 213 | -(void)caClose{ 214 | [self addNumToLabel]; 215 | 216 | CATransition *transitionAni = [CATransition animation]; 217 | transitionAni.type = @"cameraIrisHollowClose"; 218 | transitionAni.subtype = kCATransitionFromRight; 219 | transitionAni.duration = 1.0f; 220 | [self.babyView.layer addAnimation:transitionAni forKey:@"caCloseAnimation"]; 221 | } 222 | 223 | 224 | 225 | @end 226 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/MCFireworksButton/MCFireworksButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCFireworksButton.h 3 | // MCFireworksButton 4 | // 5 | // Created by Matthew Cheok on 17/3/14. 6 | // Copyright (c) 2014 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MCFireworksButton : UIButton 12 | 13 | @property (strong, nonatomic) UIImage *particleImage; 14 | @property (assign, nonatomic) CGFloat particleScale; 15 | @property (assign, nonatomic) CGFloat particleScaleRange; 16 | 17 | - (void)animate; 18 | - (void)popOutsideWithDuration:(NSTimeInterval)duration; 19 | - (void)popInsideWithDuration:(NSTimeInterval)duration; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/MCFireworksButton/MCFireworksButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCFireworksButton.m 3 | // MCFireworksButton 4 | // 5 | // Created by Matthew Cheok on 17/3/14. 6 | // Copyright (c) 2014 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | #import "MCFireworksButton.h" 10 | #import "MCFireworksView.h" 11 | 12 | @interface MCFireworksButton () 13 | 14 | @property (strong, nonatomic) MCFireworksView *fireworksView; 15 | 16 | @end 17 | 18 | @implementation MCFireworksButton 19 | 20 | - (void)setup { 21 | self.clipsToBounds = NO; 22 | 23 | _fireworksView = [[MCFireworksView alloc] init]; 24 | [self insertSubview:_fireworksView atIndex:0]; 25 | } 26 | 27 | - (id)initWithFrame:(CGRect)frame { 28 | self = [super initWithFrame:frame]; 29 | if (self) { 30 | [self setup]; 31 | } 32 | return self; 33 | } 34 | 35 | - (id)initWithCoder:(NSCoder *)aDecoder { 36 | self = [super initWithCoder:aDecoder]; 37 | if (self) { 38 | [self setup]; 39 | } 40 | return self; 41 | } 42 | 43 | - (void)layoutSubviews { 44 | [super layoutSubviews]; 45 | self.fireworksView.frame = self.bounds; 46 | 47 | [self insertSubview:self.fireworksView atIndex:0]; 48 | } 49 | 50 | #pragma mark - Methods 51 | 52 | - (void)animate { 53 | [self.fireworksView animate]; 54 | } 55 | 56 | - (void)popOutsideWithDuration:(NSTimeInterval)duration { 57 | __weak typeof(self) weakSelf = self; 58 | self.transform = CGAffineTransformIdentity; 59 | [UIView animateKeyframesWithDuration:duration delay:0 options:0 animations: ^{ 60 | [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 / 3.0 animations: ^{ 61 | typeof(self) strongSelf = weakSelf; 62 | strongSelf.transform = CGAffineTransformMakeScale(1.5, 1.5); 63 | }]; 64 | [UIView addKeyframeWithRelativeStartTime:1/3.0 relativeDuration:1/3.0 animations: ^{ 65 | typeof(self) strongSelf = weakSelf; 66 | strongSelf.transform = CGAffineTransformMakeScale(0.8, 0.8); 67 | }]; 68 | [UIView addKeyframeWithRelativeStartTime:2/3.0 relativeDuration:1/3.0 animations: ^{ 69 | typeof(self) strongSelf = weakSelf; 70 | strongSelf.transform = CGAffineTransformMakeScale(1.0, 1.0); 71 | }]; 72 | } completion:nil]; 73 | } 74 | 75 | - (void)popInsideWithDuration:(NSTimeInterval)duration { 76 | __weak typeof(self) weakSelf = self; 77 | self.transform = CGAffineTransformIdentity; 78 | [UIView animateKeyframesWithDuration:duration delay:0 options:0 animations: ^{ 79 | [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 / 2.0 animations: ^{ 80 | typeof(self) strongSelf = weakSelf; 81 | strongSelf.transform = CGAffineTransformMakeScale(0.8, 0.8); 82 | }]; 83 | [UIView addKeyframeWithRelativeStartTime:1/2.0 relativeDuration:1/2.0 animations: ^{ 84 | typeof(self) strongSelf = weakSelf; 85 | strongSelf.transform = CGAffineTransformMakeScale(1.0, 1.0); 86 | }]; 87 | } completion:nil]; 88 | } 89 | 90 | #pragma mark - Properties 91 | 92 | - (UIImage *)particleImage { 93 | return self.fireworksView.particleImage; 94 | } 95 | 96 | - (void)setParticleImage:(UIImage *)particleImage { 97 | self.fireworksView.particleImage = particleImage; 98 | } 99 | 100 | - (CGFloat)particleScale { 101 | return self.fireworksView.particleScale; 102 | } 103 | 104 | - (void)setParticleScale:(CGFloat)particleScale { 105 | self.fireworksView.particleScale = particleScale; 106 | } 107 | 108 | - (CGFloat)particleScaleRange { 109 | return self.fireworksView.particleScaleRange; 110 | } 111 | 112 | - (void)setParticleScaleRange:(CGFloat)particleScaleRange { 113 | self.fireworksView.particleScaleRange = particleScaleRange; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/MCFireworksButton/MCFireworksView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCFireworksView.h 3 | // MCFireworksButton 4 | // 5 | // Created by Matthew Cheok on 17/3/14. 6 | // Copyright (c) 2014 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MCFireworksView : UIView 12 | 13 | @property (strong, nonatomic) UIImage *particleImage; 14 | @property (assign, nonatomic) CGFloat particleScale; 15 | @property (assign, nonatomic) CGFloat particleScaleRange; 16 | 17 | - (void)animate; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/MCFireworksButton/MCFireworksView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCFireworksView.m 3 | // MCFireworksButton 4 | // 5 | // Created by Matthew Cheok on 17/3/14. 6 | // Copyright (c) 2014 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | #import "MCFireworksView.h" 10 | 11 | @interface MCFireworksView () 12 | 13 | @property (strong, nonatomic) NSArray *emitterCells; 14 | @property (strong, nonatomic) CAEmitterLayer *chargeLayer; 15 | @property (strong, nonatomic) CAEmitterLayer *explosionLayer; 16 | 17 | @end 18 | 19 | @implementation MCFireworksView 20 | 21 | - (void)setup { 22 | self.clipsToBounds = NO; 23 | self.userInteractionEnabled = NO; 24 | 25 | CAEmitterCell *explosionCell = [CAEmitterCell emitterCell]; 26 | explosionCell.name = @"explosion"; 27 | explosionCell.alphaRange = 0.20; 28 | explosionCell.alphaSpeed = -1.0; 29 | 30 | explosionCell.lifetime = 0.7; 31 | explosionCell.lifetimeRange = 0.3; 32 | explosionCell.birthRate = 0; 33 | explosionCell.velocity = 40.00; 34 | explosionCell.velocityRange = 10.00; 35 | 36 | _explosionLayer = [CAEmitterLayer layer]; 37 | _explosionLayer.name = @"emitterLayer"; 38 | _explosionLayer.emitterShape = kCAEmitterLayerCircle; 39 | _explosionLayer.emitterMode = kCAEmitterLayerOutline; 40 | _explosionLayer.emitterSize = CGSizeMake(25, 0); 41 | _explosionLayer.emitterCells = @[explosionCell]; 42 | _explosionLayer.renderMode = kCAEmitterLayerOldestFirst; 43 | _explosionLayer.masksToBounds = NO; 44 | _explosionLayer.seed = 1366128504; 45 | [self.layer addSublayer:_explosionLayer]; 46 | 47 | CAEmitterCell *chargeCell = [CAEmitterCell emitterCell]; 48 | chargeCell.name = @"charge"; 49 | chargeCell.alphaRange = 0.20; 50 | chargeCell.alphaSpeed = -1.0; 51 | 52 | chargeCell.lifetime = 0.3; 53 | chargeCell.lifetimeRange = 0.1; 54 | chargeCell.birthRate = 0; 55 | chargeCell.velocity = -40.0; 56 | chargeCell.velocityRange = 0.00; 57 | 58 | _chargeLayer = [CAEmitterLayer layer]; 59 | _chargeLayer.name = @"emitterLayer"; 60 | _chargeLayer.emitterShape = kCAEmitterLayerCircle; 61 | _chargeLayer.emitterMode = kCAEmitterLayerOutline; 62 | _chargeLayer.emitterSize = CGSizeMake(25, 0); 63 | _chargeLayer.emitterCells = @[chargeCell]; 64 | _chargeLayer.renderMode = kCAEmitterLayerOldestFirst; 65 | _chargeLayer.masksToBounds = NO; 66 | _chargeLayer.seed = 1366128504; 67 | [self.layer addSublayer:_chargeLayer]; 68 | 69 | self.emitterCells = @[chargeCell, explosionCell]; 70 | } 71 | 72 | - (id)initWithFrame:(CGRect)frame { 73 | self = [super initWithFrame:frame]; 74 | if (self) { 75 | [self setup]; 76 | } 77 | return self; 78 | } 79 | 80 | - (id)initWithCoder:(NSCoder *)aDecoder { 81 | self = [super initWithCoder:aDecoder]; 82 | if (self) { 83 | [self setup]; 84 | } 85 | return self; 86 | } 87 | 88 | - (void)layoutSubviews { 89 | [super layoutSubviews]; 90 | CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 91 | self.chargeLayer.emitterPosition = center; 92 | self.explosionLayer.emitterPosition = center; 93 | } 94 | 95 | #pragma mark - Methods 96 | 97 | - (void)animate { 98 | self.chargeLayer.beginTime = CACurrentMediaTime(); 99 | [self.chargeLayer setValue:@80 forKeyPath:@"emitterCells.charge.birthRate"]; 100 | [self performSelector:@selector(explode) withObject:nil afterDelay:0.2]; 101 | } 102 | 103 | - (void)explode { 104 | [self.chargeLayer setValue:@0 forKeyPath:@"emitterCells.charge.birthRate"]; 105 | self.explosionLayer.beginTime = CACurrentMediaTime(); 106 | [self.explosionLayer setValue:@500 forKeyPath:@"emitterCells.explosion.birthRate"]; 107 | [self performSelector:@selector(stop) withObject:nil afterDelay:0.1]; 108 | } 109 | 110 | - (void)stop { 111 | [self.chargeLayer setValue:@0 forKeyPath:@"emitterCells.charge.birthRate"]; 112 | [self.explosionLayer setValue:@0 forKeyPath:@"emitterCells.explosion.birthRate"]; 113 | } 114 | 115 | #pragma mark - Properties 116 | 117 | - (void)setParticleImage:(UIImage *)particleImage { 118 | _particleImage = particleImage; 119 | for (CAEmitterCell *cell in self.emitterCells) { 120 | cell.contents = (id)[particleImage CGImage]; 121 | } 122 | } 123 | 124 | - (void)setParticleScale:(CGFloat)particleScale { 125 | _particleScale = particleScale; 126 | for (CAEmitterCell *cell in self.emitterCells) { 127 | cell.scale = particleScale; 128 | } 129 | } 130 | 131 | - (void)setParticleScaleRange:(CGFloat)particleScaleRange { 132 | _particleScaleRange = particleScaleRange; 133 | for (CAEmitterCell *cell in self.emitterCells) { 134 | cell.scaleRange = particleScaleRange; 135 | } 136 | } 137 | 138 | @end 139 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/ProgressView/GJProgressAniView.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // GJProgressAniView.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/4/2. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | @interface GJProgressAniView : UIView 14 | 15 | @property(nonatomic,assign)CGFloat mainPathWidth; 16 | 17 | - (void)drawCircleWithProgress:(NSInteger)progress; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/ProgressView/GJProgressAniView.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // GJProgressAniView.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/4/2. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "GJProgressAniView.h" 12 | 13 | @interface GJProgressAniView() 14 | @property(nonatomic,strong)UILabel *proLabel; 15 | @property(nonatomic,assign)NSInteger proLabelNum; 16 | @property(nonatomic,assign)NSInteger progress; 17 | @property(nonatomic,strong)CAGradientLayer *gradient; 18 | @property(nonatomic,strong)CAShapeLayer *backPathLayer; 19 | @property(nonatomic,strong)CAShapeLayer *mainPathLayer; 20 | @property(nonatomic,strong)NSTimer *proLabelTimer; 21 | @end 22 | 23 | @implementation GJProgressAniView 24 | - (UILabel *)proLabel{ 25 | if (_proLabel == nil){ 26 | _proLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)]; 27 | _proLabel.center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); 28 | _proLabel.textAlignment = NSTextAlignmentCenter; 29 | _proLabel.font = [UIFont systemFontOfSize:self.bounds.size.width / 6]; 30 | _proLabel.text = @""; 31 | [self addSubview:_proLabel]; 32 | } 33 | return _proLabel; 34 | } 35 | 36 | - (CAShapeLayer *)backPathLayer{ 37 | if (_backPathLayer == nil){ 38 | _backPathLayer = [[CAShapeLayer alloc] init]; 39 | _backPathLayer.fillColor = [UIColor clearColor].CGColor; 40 | _backPathLayer.strokeColor = [[UIColor whiteColor] colorWithAlphaComponent:0.5].CGColor; 41 | _backPathLayer.lineWidth = self.mainPathWidth; 42 | [self.layer addSublayer:_backPathLayer]; 43 | } 44 | return _backPathLayer; 45 | } 46 | 47 | - (CAShapeLayer *)mainPathLayer{ 48 | if (_mainPathLayer == nil){ 49 | _mainPathLayer = [[CAShapeLayer alloc] init]; 50 | _mainPathLayer.fillColor = [UIColor clearColor].CGColor; 51 | _mainPathLayer.strokeColor = [UIColor whiteColor].CGColor; 52 | _mainPathLayer.lineWidth = self.mainPathWidth; 53 | [self.layer addSublayer:_mainPathLayer]; 54 | } 55 | return _mainPathLayer; 56 | } 57 | 58 | - (CAGradientLayer *)gradient{ 59 | if (_gradient == nil){ 60 | _gradient = [[CAGradientLayer alloc] init]; 61 | _gradient.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); 62 | [_gradient setColors:[NSArray arrayWithObjects:(id)[[self switchHexStringToColor:@"f31414"] CGColor], (id)[[self switchHexStringToColor:@"f27200"] CGColor],(id)[[self switchHexStringToColor:@"ffff00"] CGColor],(id)[[self switchHexStringToColor:@"2bee22"] CGColor],(id)[[self switchHexStringToColor:@"32a7eb"] CGColor],nil]]; 63 | [_gradient setLocations:@[@0,@0.3,@0.7,@1]]; 64 | [_gradient setStartPoint:CGPointMake(0, 0)]; 65 | [_gradient setEndPoint:CGPointMake(1, 0)]; 66 | _gradient.type = kCAGradientLayerAxial; 67 | [self.layer addSublayer:_gradient]; 68 | } 69 | return _gradient; 70 | } 71 | 72 | - (UIColor *)switchHexStringToColor:(NSString *)hexString{ 73 | NSString *cString = [[hexString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; 74 | 75 | // String should be 6 or 8 characters 76 | if ([cString length] < 6) { 77 | return [UIColor clearColor]; 78 | } 79 | 80 | // strip 0X if it appears 81 | if ([cString hasPrefix:@"0X"]) 82 | cString = [cString substringFromIndex:2]; 83 | if ([cString hasPrefix:@"#"]) 84 | cString = [cString substringFromIndex:1]; 85 | if ([cString length] != 6) 86 | return [UIColor clearColor]; 87 | 88 | // Separate into r, g, b substrings 89 | NSRange range; 90 | range.location = 0; 91 | range.length = 2; 92 | 93 | //r 94 | NSString *rString = [cString substringWithRange:range]; 95 | 96 | //g 97 | range.location = 2; 98 | NSString *gString = [cString substringWithRange:range]; 99 | 100 | //b 101 | range.location = 4; 102 | NSString *bString = [cString substringWithRange:range]; 103 | 104 | // Scan values 105 | unsigned int r, g, b; 106 | [[NSScanner scannerWithString:rString] scanHexInt:&r]; 107 | [[NSScanner scannerWithString:gString] scanHexInt:&g]; 108 | [[NSScanner scannerWithString:bString] scanHexInt:&b]; 109 | 110 | return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f]; 111 | } 112 | 113 | - (void)drawCircleWithProgress:(NSInteger)progress{ 114 | self.progress = progress; 115 | self.proLabelNum = 0; 116 | 117 | UIBezierPath *backPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:self.bounds.size.width/2 - self.mainPathWidth startAngle:M_PI endAngle:M_PI*3 clockwise:YES]; 118 | 119 | UIBezierPath *mainPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:self.bounds.size.width/2 - self.mainPathWidth + 3 startAngle:M_PI endAngle:M_PI*3 clockwise:YES]; 120 | 121 | self.backPathLayer.path = backPath.CGPath; 122 | self.mainPathLayer.path = mainPath.CGPath; 123 | 124 | [self.gradient setMask:self.mainPathLayer]; 125 | 126 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 127 | animation.duration = progress/100.0f; 128 | animation.fromValue = [NSNumber numberWithFloat:0.0f]; 129 | animation.toValue = [NSNumber numberWithFloat:progress/100.0f]; 130 | animation.fillMode = kCAFillModeForwards; 131 | animation.removedOnCompletion = NO; 132 | [self.mainPathLayer addAnimation:animation forKey:@"strokeEndAnimation"]; 133 | 134 | if (self.progress > 0){ 135 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 136 | self.proLabelTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(proLabelTimerAction) userInfo:nil repeats:YES]; 137 | [[NSRunLoop currentRunLoop] run]; 138 | }); 139 | }else{ 140 | self.proLabel.text = @"0%"; 141 | } 142 | } 143 | 144 | - (void)proLabelTimerAction{ 145 | dispatch_async(dispatch_get_main_queue(), ^{ 146 | self.proLabel.text = [NSString stringWithFormat:@"%ld%%",(long)self.proLabelNum]; 147 | }); 148 | 149 | if (self.proLabelNum >= self.progress){ 150 | [self.proLabelTimer invalidate]; 151 | self.proLabelTimer = nil; 152 | }else{ 153 | self.proLabelNum++; 154 | } 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Sounds/bloom.caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Sounds/bloom.caf -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Sounds/fold.caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Sounds/fold.caf -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/Sounds/selected.caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manofit/BabyPigAnimation/c4be182eddc6910cc74364533d39588fe9fb4ccd/BabyPigAnimation/BabyPigAnimation/Sounds/selected.caf -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/ViewController.h: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // ViewController.h 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | @interface ViewController : UIViewController 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/ViewController.m: -------------------------------------------------------------------------------- 1 | // 您好,谢谢您参考我的项目,如果有问题请移步 2 | // https://github.com/manofit/BabyPigAnimation 3 | // 4 | // ViewController.m 5 | // BabyPigAnimation 6 | // 7 | // Created by 高军 on 2018/3/27. 8 | // Copyright © 2018年 Jun Gao. All rights reserved. 9 | // 10 | 11 | #import "ViewController.h" 12 | #import "BaseAnimationViewController.h" 13 | #import "KeyFrameAnimationViewController.h" 14 | #import "GroupAnimationViewController.h" 15 | #import "TransitionAnimationViewController.h" 16 | #import "CombinationAniViewController.h" 17 | 18 | @interface ViewController () 19 | { 20 | UITableView *_tableView; 21 | NSArray *_dataArray; 22 | } 23 | @end 24 | 25 | @implementation ViewController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view, typically from a nib. 30 | 31 | self.navigationItem.title = @"iOS动画"; 32 | 33 | [self createUI]; 34 | [self configData]; 35 | 36 | } 37 | 38 | -(void)createUI{ 39 | _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64) style:UITableViewStyleGrouped]; 40 | _tableView.delegate = self; 41 | _tableView.dataSource = self; 42 | [self.view addSubview:_tableView]; 43 | } 44 | 45 | -(void)configData{ 46 | NSArray *array_1 = [NSArray arrayWithObjects:@"位移",@"透明度",@"缩放",@"旋转",@"背景色", nil]; 47 | NSMutableDictionary *dic_1 = [NSMutableDictionary dictionaryWithObject:array_1 forKey:@"value"]; 48 | [dic_1 setValue:@"基础动画" forKey:@"title"]; 49 | 50 | NSArray *array_2 = [NSArray arrayWithObjects:@"关键帧",@"路径",@"抖动", nil]; 51 | NSMutableDictionary *dic_2 = [NSMutableDictionary dictionaryWithObject:array_2 forKey:@"value"]; 52 | [dic_2 setValue:@"关键帧动画" forKey:@"title"]; 53 | 54 | NSArray *array_3 = [NSArray arrayWithObjects:@"同时",@"连续", nil]; 55 | NSMutableDictionary *dic_3 = [NSMutableDictionary dictionaryWithObject:array_3 forKey:@"value"]; 56 | [dic_3 setValue:@"组动画" forKey:@"title"]; 57 | 58 | NSArray *array_4 = [NSArray arrayWithObjects:@"fade",@"moveIn",@"push",@"reveal",@"cube",@"suck",@"oglFile",@"ripple",@"curl",@"unCurl",@"caOpen",@"caClose", nil]; 59 | NSMutableDictionary *dic_4 = [NSMutableDictionary dictionaryWithObject:array_4 forKey:@"value"]; 60 | [dic_4 setValue:@"过渡动画" forKey:@"title"]; 61 | 62 | NSArray *array_5 = [NSArray arrayWithObjects:@"path",@"钉钉",@"点赞",@"贝塞尔曲线",@"进度", nil]; 63 | NSMutableDictionary *dic_5 = [NSMutableDictionary dictionaryWithObject:array_5 forKey:@"value"]; 64 | [dic_5 setValue:@"组合案例" forKey:@"title"]; 65 | 66 | _dataArray = @[dic_1,dic_2,dic_3,dic_4,dic_5]; 67 | 68 | [_tableView reloadData]; 69 | 70 | } 71 | 72 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 73 | return 5; 74 | } 75 | 76 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 77 | NSDictionary *dic = _dataArray[section]; 78 | NSArray *array = dic[@"value"]; 79 | return array.count; 80 | } 81 | 82 | -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ 83 | NSDictionary *dic = _dataArray[section]; 84 | return dic[@"title"]; 85 | } 86 | 87 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 88 | static NSString *cellid = @"cellID"; 89 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellid]; 90 | if (nil == cell){ 91 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellid]; 92 | } 93 | cell.textLabel.text = _dataArray[indexPath.section][@"value"][indexPath.row]; 94 | 95 | return cell; 96 | } 97 | 98 | -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ 99 | return 0.1; 100 | } 101 | 102 | -(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{ 103 | UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 0.1)]; 104 | view.backgroundColor = [UIColor clearColor]; 105 | return view; 106 | } 107 | 108 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 109 | if (indexPath.section == 0){ 110 | BaseAnimationViewController *vc = [[BaseAnimationViewController alloc] initWithType:indexPath.row]; 111 | [self.navigationController pushViewController:vc animated:YES]; 112 | }else if (indexPath.section == 1){ 113 | KeyFrameAnimationViewController *vc = [[KeyFrameAnimationViewController alloc] initWithType:indexPath.row]; 114 | [self.navigationController pushViewController:vc animated:YES]; 115 | }else if (indexPath.section == 2){ 116 | GroupAnimationViewController *vc = [[GroupAnimationViewController alloc] initWithType:indexPath.row]; 117 | [self.navigationController pushViewController:vc animated:YES]; 118 | }else if (indexPath.section == 3){ 119 | TransitionAnimationViewController *vc = [[TransitionAnimationViewController alloc] initWithType:indexPath.row]; 120 | [self.navigationController pushViewController:vc animated:YES]; 121 | }else if (indexPath.section == 4){ 122 | CombinationAniViewController *vc = [[CombinationAniViewController alloc] initWithType:indexPath.row]; 123 | [self.navigationController pushViewController:vc animated:YES]; 124 | } 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimation/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BabyPigAnimation 4 | // 5 | // Created by 高军 on 2018/3/27. 6 | // Copyright © 2018年 Jun Gao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimationTests/BabyPigAnimationTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BabyPigAnimationTests.m 3 | // BabyPigAnimationTests 4 | // 5 | // Created by 高军 on 2018/3/27. 6 | // Copyright © 2018年 Jun Gao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BabyPigAnimationTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BabyPigAnimationTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimationTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimationUITests/BabyPigAnimationUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BabyPigAnimationUITests.m 3 | // BabyPigAnimationUITests 4 | // 5 | // Created by 高军 on 2018/3/27. 6 | // Copyright © 2018年 Jun Gao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BabyPigAnimationUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BabyPigAnimationUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /BabyPigAnimation/BabyPigAnimationUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BabyPigAnimation 2 | 3 | 从简单的基础动画到复杂的组动画,原理一目了然。最后再加上几个常见动画,举一反三。 4 | ### 效果图 5 | ![gif_1](https://github.com/manofit/ScreenPics/blob/master/PigAnimation_Pics/gif_1.gif)![gif_2](https://github.com/manofit/ScreenPics/blob/master/PigAnimation_Pics/gif_2.gif)![gif_3](https://github.com/manofit/ScreenPics/blob/master/PigAnimation_Pics/gif_3.gif)![love](https://github.com/manofit/ScreenPics/blob/master/PigAnimation_Pics/love.gif)![progress](https://github.com/manofit/ScreenPics/blob/master/PigAnimation_Pics/progress.gif) 6 | 7 | 8 | ### 使用 9 | - 基础动画 10 | ``` 11 | //位移 12 | -(void)makePositionAnimation{ 13 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; 14 | animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2-75)]; 15 | animation.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH-50, SCREEN_HEIGHT/2-75)]; 16 | animation.duration = 1.0f; 17 | //animation.fillMode = kCAFillModeForwards; 18 | //animation.removedOnCompletion = NO; 19 | [self.babyView.layer addAnimation:animation forKey:@"positionAnimation"]; 20 | } 21 | ``` 22 | - 关键帧动画 23 | ``` 24 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 25 | NSValue *value_0 = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2-50)]; 26 | NSValue *value_1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)]; 27 | NSValue *value_2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)]; 28 | NSValue *value_3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)]; 29 | NSValue *value_4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)]; 30 | NSValue *value_5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH-50, SCREEN_HEIGHT/2-50)]; 31 | animation.values = [NSArray arrayWithObjects:value_0,value_1,value_2,value_3,value_4,value_5, nil]; 32 | animation.duration = 2.0f; 33 | [self.babyView.layer addAnimation:animation forKey:@"keyFrameAnimation"]; 34 | ``` 35 | - 组动画 36 | ``` 37 | CAKeyframeAnimation *positionAni = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 38 | NSValue *value_0 = [NSValue valueWithCGPoint:CGPointMake(50, SCREEN_HEIGHT/2-50)]; 39 | NSValue *value_1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)]; 40 | NSValue *value_2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)]; 41 | NSValue *value_3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)]; 42 | NSValue *value_4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)]; 43 | NSValue *value_5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH-50, SCREEN_HEIGHT/2-50)]; 44 | positionAni.values = [NSArray arrayWithObjects:value_0,value_1,value_2,value_3,value_4,value_5, nil]; 45 | 46 | CABasicAnimation *scaleAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 47 | scaleAni.fromValue = [NSNumber numberWithFloat:0.8f]; 48 | scaleAni.toValue = [NSNumber numberWithFloat:2.0f]; 49 | 50 | CABasicAnimation *rotateAni = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; 51 | rotateAni.toValue = [NSNumber numberWithFloat:M_PI*4]; 52 | 53 | CAAnimationGroup *groupAni = [CAAnimationGroup animation]; 54 | groupAni.animations = [NSArray arrayWithObjects:positionAni,scaleAni,rotateAni, nil]; 55 | groupAni.duration = 4.0f; 56 | [self.babyView.layer addAnimation:groupAni forKey:@"groupAnimation"]; 57 | ``` 58 | - 过渡动画 59 | ``` 60 | CATransition *transitionAni = [CATransition animation]; 61 | transitionAni.type = kCATransitionMoveIn; 62 | transitionAni.subtype = kCATransitionFromRight; 63 | transitionAni.duration = 1.0f; 64 | [self.babyView.layer addAnimation:transitionAni forKey:@"moveInAnimation"]; 65 | ``` 66 | --------------------------------------------------------------------------------