├── .gitignore ├── ARNZoomImageTransition ├── ARNZoomImageTransition.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── ARNZoomImageTransition.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── ARNZoomImageTransition │ ├── Animation │ │ └── ImageZoomAnimation.swift │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Cell │ │ ├── CollectionCell.swift │ │ ├── CollectionCell.xib │ │ ├── TableCell.swift │ │ └── TableCell.xib │ ├── Controller │ │ ├── DetailViewController.storyboard │ │ ├── DetailViewController.swift │ │ ├── MainViewController.storyboard │ │ ├── MainViewController.swift │ │ ├── ModalViewController.storyboard │ │ └── ModalViewController.swift │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Supporting Files │ │ └── Info.plist │ └── mos.jpg ├── ARNZoomImageTransitionTests │ ├── ARNZoomImageTransitionTests.swift │ └── Supporting Files │ │ └── Info.plist ├── Podfile └── Podfile.lock ├── LICENSE ├── README.md └── capture.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | *.moved-aside 17 | DerivedData 18 | *.hmap 19 | *.ipa 20 | *.xcuserstate 21 | 22 | # CocoaPods 23 | Pods/ 24 | 25 | # Carthage 26 | Carthage/Build 27 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9115E1C32099FCA200F26C0C /* ImageZoomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9115E1C22099FCA200F26C0C /* ImageZoomAnimation.swift */; }; 11 | 9170B01A1B75A11B002BE0A7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B0191B75A11B002BE0A7 /* AppDelegate.swift */; }; 12 | 9170B0211B75A11B002BE0A7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9170B0201B75A11B002BE0A7 /* Images.xcassets */; }; 13 | 9170B0241B75A11B002BE0A7 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9170B0221B75A11B002BE0A7 /* LaunchScreen.xib */; }; 14 | 9170B0301B75A11B002BE0A7 /* ARNZoomImageTransitionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B02F1B75A11B002BE0A7 /* ARNZoomImageTransitionTests.swift */; }; 15 | 9170B03F1B75BA13002BE0A7 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B03E1B75BA13002BE0A7 /* DetailViewController.swift */; }; 16 | 9170B0411B75BA57002BE0A7 /* DetailViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9170B0401B75BA57002BE0A7 /* DetailViewController.storyboard */; }; 17 | 9170B0451B75BB47002BE0A7 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B0441B75BB47002BE0A7 /* MainViewController.swift */; }; 18 | 9170B0471B75BB64002BE0A7 /* MainViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9170B0461B75BB64002BE0A7 /* MainViewController.storyboard */; }; 19 | 9170B0491B75BDCE002BE0A7 /* CollectionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9170B0481B75BDCE002BE0A7 /* CollectionCell.xib */; }; 20 | 9170B04B1B75BDDF002BE0A7 /* TableCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9170B04A1B75BDDF002BE0A7 /* TableCell.xib */; }; 21 | 9170B04D1B75BDF9002BE0A7 /* TableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B04C1B75BDF9002BE0A7 /* TableCell.swift */; }; 22 | 9170B04F1B75BE6F002BE0A7 /* CollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B04E1B75BE6F002BE0A7 /* CollectionCell.swift */; }; 23 | 9170B0511B761192002BE0A7 /* ModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9170B0501B761192002BE0A7 /* ModalViewController.swift */; }; 24 | 9170B0531B7611AD002BE0A7 /* ModalViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9170B0521B7611AD002BE0A7 /* ModalViewController.storyboard */; }; 25 | 91F37EB41B7634C700B15EBD /* mos.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 91F37EB31B7634C700B15EBD /* mos.jpg */; }; 26 | BC01B91AF2F9BA3634DED98E /* Pods_ARNZoomImageTransition.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AED5B8DBF3EDF69A99FBD2E /* Pods_ARNZoomImageTransition.framework */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 9170B02A1B75A11B002BE0A7 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 9170B00C1B75A11B002BE0A7 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 9170B0131B75A11B002BE0A7; 35 | remoteInfo = ARNZoomImageTransition; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 409342D75B99ED5D861C450E /* Pods-ARNZoomImageTransition.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ARNZoomImageTransition.release.xcconfig"; path = "Pods/Target Support Files/Pods-ARNZoomImageTransition/Pods-ARNZoomImageTransition.release.xcconfig"; sourceTree = ""; }; 41 | 7AED5B8DBF3EDF69A99FBD2E /* Pods_ARNZoomImageTransition.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ARNZoomImageTransition.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 9115E1C22099FCA200F26C0C /* ImageZoomAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageZoomAnimation.swift; sourceTree = ""; }; 43 | 9170B0141B75A11B002BE0A7 /* ARNZoomImageTransition.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ARNZoomImageTransition.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 9170B0181B75A11B002BE0A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 9170B0191B75A11B002BE0A7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46 | 9170B0201B75A11B002BE0A7 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 47 | 9170B0231B75A11B002BE0A7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 48 | 9170B0291B75A11B002BE0A7 /* ARNZoomImageTransitionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ARNZoomImageTransitionTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 9170B02E1B75A11B002BE0A7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 9170B02F1B75A11B002BE0A7 /* ARNZoomImageTransitionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARNZoomImageTransitionTests.swift; sourceTree = ""; }; 51 | 9170B03E1B75BA13002BE0A7 /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; 52 | 9170B0401B75BA57002BE0A7 /* DetailViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = DetailViewController.storyboard; sourceTree = ""; }; 53 | 9170B0441B75BB47002BE0A7 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 54 | 9170B0461B75BB64002BE0A7 /* MainViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainViewController.storyboard; sourceTree = ""; }; 55 | 9170B0481B75BDCE002BE0A7 /* CollectionCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CollectionCell.xib; sourceTree = ""; }; 56 | 9170B04A1B75BDDF002BE0A7 /* TableCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TableCell.xib; sourceTree = ""; }; 57 | 9170B04C1B75BDF9002BE0A7 /* TableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCell.swift; sourceTree = ""; }; 58 | 9170B04E1B75BE6F002BE0A7 /* CollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionCell.swift; sourceTree = ""; }; 59 | 9170B0501B761192002BE0A7 /* ModalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalViewController.swift; sourceTree = ""; }; 60 | 9170B0521B7611AD002BE0A7 /* ModalViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ModalViewController.storyboard; sourceTree = ""; }; 61 | 91F37EB31B7634C700B15EBD /* mos.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = mos.jpg; sourceTree = ""; }; 62 | AA7538BEF5F678A022822209 /* Pods-ARNZoomImageTransition.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ARNZoomImageTransition.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ARNZoomImageTransition/Pods-ARNZoomImageTransition.debug.xcconfig"; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 9170B0111B75A11B002BE0A7 /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | BC01B91AF2F9BA3634DED98E /* Pods_ARNZoomImageTransition.framework in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 9170B0261B75A11B002BE0A7 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 04936135AD7ECCF114ED211B /* Pods */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | AA7538BEF5F678A022822209 /* Pods-ARNZoomImageTransition.debug.xcconfig */, 88 | 409342D75B99ED5D861C450E /* Pods-ARNZoomImageTransition.release.xcconfig */, 89 | ); 90 | name = Pods; 91 | sourceTree = ""; 92 | }; 93 | 2A3244743CB2ED90AF72E3AE /* Frameworks */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 7AED5B8DBF3EDF69A99FBD2E /* Pods_ARNZoomImageTransition.framework */, 97 | ); 98 | name = Frameworks; 99 | sourceTree = ""; 100 | }; 101 | 9170B00B1B75A11B002BE0A7 = { 102 | isa = PBXGroup; 103 | children = ( 104 | 9170B0161B75A11B002BE0A7 /* ARNZoomImageTransition */, 105 | 9170B02C1B75A11B002BE0A7 /* ARNZoomImageTransitionTests */, 106 | 9170B0151B75A11B002BE0A7 /* Products */, 107 | 04936135AD7ECCF114ED211B /* Pods */, 108 | 2A3244743CB2ED90AF72E3AE /* Frameworks */, 109 | ); 110 | sourceTree = ""; 111 | }; 112 | 9170B0151B75A11B002BE0A7 /* Products */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 9170B0141B75A11B002BE0A7 /* ARNZoomImageTransition.app */, 116 | 9170B0291B75A11B002BE0A7 /* ARNZoomImageTransitionTests.xctest */, 117 | ); 118 | name = Products; 119 | sourceTree = ""; 120 | }; 121 | 9170B0161B75A11B002BE0A7 /* ARNZoomImageTransition */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 9170B0191B75A11B002BE0A7 /* AppDelegate.swift */, 125 | 9170B0391B75A122002BE0A7 /* Animation */, 126 | 91F37EB51B7634D800B15EBD /* Controller */, 127 | 91F37EB61B7634E800B15EBD /* Cell */, 128 | 91F37EB31B7634C700B15EBD /* mos.jpg */, 129 | 9170B0201B75A11B002BE0A7 /* Images.xcassets */, 130 | 9170B0221B75A11B002BE0A7 /* LaunchScreen.xib */, 131 | 9170B0171B75A11B002BE0A7 /* Supporting Files */, 132 | ); 133 | path = ARNZoomImageTransition; 134 | sourceTree = ""; 135 | }; 136 | 9170B0171B75A11B002BE0A7 /* Supporting Files */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 9170B0181B75A11B002BE0A7 /* Info.plist */, 140 | ); 141 | path = "Supporting Files"; 142 | sourceTree = ""; 143 | }; 144 | 9170B02C1B75A11B002BE0A7 /* ARNZoomImageTransitionTests */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 9170B02F1B75A11B002BE0A7 /* ARNZoomImageTransitionTests.swift */, 148 | 9170B02D1B75A11B002BE0A7 /* Supporting Files */, 149 | ); 150 | path = ARNZoomImageTransitionTests; 151 | sourceTree = ""; 152 | }; 153 | 9170B02D1B75A11B002BE0A7 /* Supporting Files */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 9170B02E1B75A11B002BE0A7 /* Info.plist */, 157 | ); 158 | path = "Supporting Files"; 159 | sourceTree = ""; 160 | }; 161 | 9170B0391B75A122002BE0A7 /* Animation */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 9115E1C22099FCA200F26C0C /* ImageZoomAnimation.swift */, 165 | ); 166 | path = Animation; 167 | sourceTree = ""; 168 | }; 169 | 91F37EB51B7634D800B15EBD /* Controller */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 9170B0441B75BB47002BE0A7 /* MainViewController.swift */, 173 | 9170B0461B75BB64002BE0A7 /* MainViewController.storyboard */, 174 | 9170B03E1B75BA13002BE0A7 /* DetailViewController.swift */, 175 | 9170B0401B75BA57002BE0A7 /* DetailViewController.storyboard */, 176 | 9170B0501B761192002BE0A7 /* ModalViewController.swift */, 177 | 9170B0521B7611AD002BE0A7 /* ModalViewController.storyboard */, 178 | ); 179 | path = Controller; 180 | sourceTree = ""; 181 | }; 182 | 91F37EB61B7634E800B15EBD /* Cell */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 9170B04E1B75BE6F002BE0A7 /* CollectionCell.swift */, 186 | 9170B0481B75BDCE002BE0A7 /* CollectionCell.xib */, 187 | 9170B04C1B75BDF9002BE0A7 /* TableCell.swift */, 188 | 9170B04A1B75BDDF002BE0A7 /* TableCell.xib */, 189 | ); 190 | path = Cell; 191 | sourceTree = ""; 192 | }; 193 | /* End PBXGroup section */ 194 | 195 | /* Begin PBXNativeTarget section */ 196 | 9170B0131B75A11B002BE0A7 /* ARNZoomImageTransition */ = { 197 | isa = PBXNativeTarget; 198 | buildConfigurationList = 9170B0331B75A11B002BE0A7 /* Build configuration list for PBXNativeTarget "ARNZoomImageTransition" */; 199 | buildPhases = ( 200 | 68CFA045C6C8024951D0EA9F /* [CP] Check Pods Manifest.lock */, 201 | 9170B0101B75A11B002BE0A7 /* Sources */, 202 | 9170B0111B75A11B002BE0A7 /* Frameworks */, 203 | 9170B0121B75A11B002BE0A7 /* Resources */, 204 | F0FDC672FA0AA0D31003D6C8 /* [CP] Embed Pods Frameworks */, 205 | ); 206 | buildRules = ( 207 | ); 208 | dependencies = ( 209 | ); 210 | name = ARNZoomImageTransition; 211 | productName = ARNZoomImageTransition; 212 | productReference = 9170B0141B75A11B002BE0A7 /* ARNZoomImageTransition.app */; 213 | productType = "com.apple.product-type.application"; 214 | }; 215 | 9170B0281B75A11B002BE0A7 /* ARNZoomImageTransitionTests */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = 9170B0361B75A11B002BE0A7 /* Build configuration list for PBXNativeTarget "ARNZoomImageTransitionTests" */; 218 | buildPhases = ( 219 | 9170B0251B75A11B002BE0A7 /* Sources */, 220 | 9170B0261B75A11B002BE0A7 /* Frameworks */, 221 | 9170B0271B75A11B002BE0A7 /* Resources */, 222 | ); 223 | buildRules = ( 224 | ); 225 | dependencies = ( 226 | 9170B02B1B75A11B002BE0A7 /* PBXTargetDependency */, 227 | ); 228 | name = ARNZoomImageTransitionTests; 229 | productName = ARNZoomImageTransitionTests; 230 | productReference = 9170B0291B75A11B002BE0A7 /* ARNZoomImageTransitionTests.xctest */; 231 | productType = "com.apple.product-type.bundle.unit-test"; 232 | }; 233 | /* End PBXNativeTarget section */ 234 | 235 | /* Begin PBXProject section */ 236 | 9170B00C1B75A11B002BE0A7 /* Project object */ = { 237 | isa = PBXProject; 238 | attributes = { 239 | LastSwiftMigration = 0700; 240 | LastSwiftUpdateCheck = 0700; 241 | LastUpgradeCheck = 1020; 242 | ORGANIZATIONNAME = xxxAIRINxxx; 243 | TargetAttributes = { 244 | 9170B0131B75A11B002BE0A7 = { 245 | CreatedOnToolsVersion = 6.4; 246 | DevelopmentTeam = P599PJHMNF; 247 | LastSwiftMigration = 1020; 248 | }; 249 | 9170B0281B75A11B002BE0A7 = { 250 | CreatedOnToolsVersion = 6.4; 251 | LastSwiftMigration = 1020; 252 | TestTargetID = 9170B0131B75A11B002BE0A7; 253 | }; 254 | }; 255 | }; 256 | buildConfigurationList = 9170B00F1B75A11B002BE0A7 /* Build configuration list for PBXProject "ARNZoomImageTransition" */; 257 | compatibilityVersion = "Xcode 3.2"; 258 | developmentRegion = English; 259 | hasScannedForEncodings = 0; 260 | knownRegions = ( 261 | English, 262 | en, 263 | Base, 264 | ); 265 | mainGroup = 9170B00B1B75A11B002BE0A7; 266 | productRefGroup = 9170B0151B75A11B002BE0A7 /* Products */; 267 | projectDirPath = ""; 268 | projectRoot = ""; 269 | targets = ( 270 | 9170B0131B75A11B002BE0A7 /* ARNZoomImageTransition */, 271 | 9170B0281B75A11B002BE0A7 /* ARNZoomImageTransitionTests */, 272 | ); 273 | }; 274 | /* End PBXProject section */ 275 | 276 | /* Begin PBXResourcesBuildPhase section */ 277 | 9170B0121B75A11B002BE0A7 /* Resources */ = { 278 | isa = PBXResourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 9170B0471B75BB64002BE0A7 /* MainViewController.storyboard in Resources */, 282 | 9170B0531B7611AD002BE0A7 /* ModalViewController.storyboard in Resources */, 283 | 9170B0411B75BA57002BE0A7 /* DetailViewController.storyboard in Resources */, 284 | 9170B0241B75A11B002BE0A7 /* LaunchScreen.xib in Resources */, 285 | 9170B0491B75BDCE002BE0A7 /* CollectionCell.xib in Resources */, 286 | 91F37EB41B7634C700B15EBD /* mos.jpg in Resources */, 287 | 9170B0211B75A11B002BE0A7 /* Images.xcassets in Resources */, 288 | 9170B04B1B75BDDF002BE0A7 /* TableCell.xib in Resources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | 9170B0271B75A11B002BE0A7 /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | ); 297 | runOnlyForDeploymentPostprocessing = 0; 298 | }; 299 | /* End PBXResourcesBuildPhase section */ 300 | 301 | /* Begin PBXShellScriptBuildPhase section */ 302 | 68CFA045C6C8024951D0EA9F /* [CP] Check Pods Manifest.lock */ = { 303 | isa = PBXShellScriptBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ); 307 | inputPaths = ( 308 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 309 | "${PODS_ROOT}/Manifest.lock", 310 | ); 311 | name = "[CP] Check Pods Manifest.lock"; 312 | outputPaths = ( 313 | "$(DERIVED_FILE_DIR)/Pods-ARNZoomImageTransition-checkManifestLockResult.txt", 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | shellPath = /bin/sh; 317 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 318 | showEnvVarsInLog = 0; 319 | }; 320 | F0FDC672FA0AA0D31003D6C8 /* [CP] Embed Pods Frameworks */ = { 321 | isa = PBXShellScriptBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | ); 325 | inputPaths = ( 326 | "${PODS_ROOT}/Target Support Files/Pods-ARNZoomImageTransition/Pods-ARNZoomImageTransition-frameworks.sh", 327 | "${BUILT_PRODUCTS_DIR}/ARNTransitionAnimator/ARNTransitionAnimator.framework", 328 | ); 329 | name = "[CP] Embed Pods Frameworks"; 330 | outputPaths = ( 331 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ARNTransitionAnimator.framework", 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | shellPath = /bin/sh; 335 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ARNZoomImageTransition/Pods-ARNZoomImageTransition-frameworks.sh\"\n"; 336 | showEnvVarsInLog = 0; 337 | }; 338 | /* End PBXShellScriptBuildPhase section */ 339 | 340 | /* Begin PBXSourcesBuildPhase section */ 341 | 9170B0101B75A11B002BE0A7 /* Sources */ = { 342 | isa = PBXSourcesBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | 9170B0511B761192002BE0A7 /* ModalViewController.swift in Sources */, 346 | 9115E1C32099FCA200F26C0C /* ImageZoomAnimation.swift in Sources */, 347 | 9170B04D1B75BDF9002BE0A7 /* TableCell.swift in Sources */, 348 | 9170B01A1B75A11B002BE0A7 /* AppDelegate.swift in Sources */, 349 | 9170B03F1B75BA13002BE0A7 /* DetailViewController.swift in Sources */, 350 | 9170B0451B75BB47002BE0A7 /* MainViewController.swift in Sources */, 351 | 9170B04F1B75BE6F002BE0A7 /* CollectionCell.swift in Sources */, 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | 9170B0251B75A11B002BE0A7 /* Sources */ = { 356 | isa = PBXSourcesBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | 9170B0301B75A11B002BE0A7 /* ARNZoomImageTransitionTests.swift in Sources */, 360 | ); 361 | runOnlyForDeploymentPostprocessing = 0; 362 | }; 363 | /* End PBXSourcesBuildPhase section */ 364 | 365 | /* Begin PBXTargetDependency section */ 366 | 9170B02B1B75A11B002BE0A7 /* PBXTargetDependency */ = { 367 | isa = PBXTargetDependency; 368 | target = 9170B0131B75A11B002BE0A7 /* ARNZoomImageTransition */; 369 | targetProxy = 9170B02A1B75A11B002BE0A7 /* PBXContainerItemProxy */; 370 | }; 371 | /* End PBXTargetDependency section */ 372 | 373 | /* Begin PBXVariantGroup section */ 374 | 9170B0221B75A11B002BE0A7 /* LaunchScreen.xib */ = { 375 | isa = PBXVariantGroup; 376 | children = ( 377 | 9170B0231B75A11B002BE0A7 /* Base */, 378 | ); 379 | name = LaunchScreen.xib; 380 | path = .; 381 | sourceTree = ""; 382 | }; 383 | /* End PBXVariantGroup section */ 384 | 385 | /* Begin XCBuildConfiguration section */ 386 | 9170B0311B75A11B002BE0A7 /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ALWAYS_SEARCH_USER_PATHS = NO; 390 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 391 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 392 | CLANG_CXX_LIBRARY = "libc++"; 393 | CLANG_ENABLE_MODULES = YES; 394 | CLANG_ENABLE_OBJC_ARC = YES; 395 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 396 | CLANG_WARN_BOOL_CONVERSION = YES; 397 | CLANG_WARN_COMMA = YES; 398 | CLANG_WARN_CONSTANT_CONVERSION = YES; 399 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 400 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 401 | CLANG_WARN_EMPTY_BODY = YES; 402 | CLANG_WARN_ENUM_CONVERSION = YES; 403 | CLANG_WARN_INFINITE_RECURSION = YES; 404 | CLANG_WARN_INT_CONVERSION = YES; 405 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 406 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 407 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 409 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 410 | CLANG_WARN_STRICT_PROTOTYPES = YES; 411 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 412 | CLANG_WARN_UNREACHABLE_CODE = YES; 413 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 414 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 415 | COPY_PHASE_STRIP = NO; 416 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 417 | ENABLE_STRICT_OBJC_MSGSEND = YES; 418 | ENABLE_TESTABILITY = YES; 419 | GCC_C_LANGUAGE_STANDARD = gnu99; 420 | GCC_DYNAMIC_NO_PIC = NO; 421 | GCC_NO_COMMON_BLOCKS = YES; 422 | GCC_OPTIMIZATION_LEVEL = 0; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 430 | GCC_WARN_UNDECLARED_SELECTOR = YES; 431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 432 | GCC_WARN_UNUSED_FUNCTION = YES; 433 | GCC_WARN_UNUSED_VARIABLE = YES; 434 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 435 | MTL_ENABLE_DEBUG_INFO = YES; 436 | ONLY_ACTIVE_ARCH = YES; 437 | SDKROOT = iphoneos; 438 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 439 | SWIFT_VERSION = 4.2; 440 | }; 441 | name = Debug; 442 | }; 443 | 9170B0321B75A11B002BE0A7 /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 448 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 449 | CLANG_CXX_LIBRARY = "libc++"; 450 | CLANG_ENABLE_MODULES = YES; 451 | CLANG_ENABLE_OBJC_ARC = YES; 452 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 453 | CLANG_WARN_BOOL_CONVERSION = YES; 454 | CLANG_WARN_COMMA = YES; 455 | CLANG_WARN_CONSTANT_CONVERSION = YES; 456 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 458 | CLANG_WARN_EMPTY_BODY = YES; 459 | CLANG_WARN_ENUM_CONVERSION = YES; 460 | CLANG_WARN_INFINITE_RECURSION = YES; 461 | CLANG_WARN_INT_CONVERSION = YES; 462 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 463 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 464 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 466 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 467 | CLANG_WARN_STRICT_PROTOTYPES = YES; 468 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 469 | CLANG_WARN_UNREACHABLE_CODE = YES; 470 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 471 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 472 | COPY_PHASE_STRIP = NO; 473 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 474 | ENABLE_NS_ASSERTIONS = NO; 475 | ENABLE_STRICT_OBJC_MSGSEND = YES; 476 | GCC_C_LANGUAGE_STANDARD = gnu99; 477 | GCC_NO_COMMON_BLOCKS = YES; 478 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 479 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 480 | GCC_WARN_UNDECLARED_SELECTOR = YES; 481 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 482 | GCC_WARN_UNUSED_FUNCTION = YES; 483 | GCC_WARN_UNUSED_VARIABLE = YES; 484 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 485 | MTL_ENABLE_DEBUG_INFO = NO; 486 | SDKROOT = iphoneos; 487 | SWIFT_COMPILATION_MODE = wholemodule; 488 | SWIFT_VERSION = 4.2; 489 | VALIDATE_PRODUCT = YES; 490 | }; 491 | name = Release; 492 | }; 493 | 9170B0341B75A11B002BE0A7 /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | baseConfigurationReference = AA7538BEF5F678A022822209 /* Pods-ARNZoomImageTransition.debug.xcconfig */; 496 | buildSettings = { 497 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 498 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 499 | DEVELOPMENT_TEAM = P599PJHMNF; 500 | INFOPLIST_FILE = "ARNZoomImageTransition/Supporting Files/Info.plist"; 501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 502 | PRODUCT_BUNDLE_IDENTIFIER = "xxxAIRINxxx.$(PRODUCT_NAME:rfc1034identifier)"; 503 | PRODUCT_NAME = "$(TARGET_NAME)"; 504 | SWIFT_VERSION = 5.0; 505 | }; 506 | name = Debug; 507 | }; 508 | 9170B0351B75A11B002BE0A7 /* Release */ = { 509 | isa = XCBuildConfiguration; 510 | baseConfigurationReference = 409342D75B99ED5D861C450E /* Pods-ARNZoomImageTransition.release.xcconfig */; 511 | buildSettings = { 512 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 513 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 514 | DEVELOPMENT_TEAM = P599PJHMNF; 515 | INFOPLIST_FILE = "ARNZoomImageTransition/Supporting Files/Info.plist"; 516 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 517 | PRODUCT_BUNDLE_IDENTIFIER = "xxxAIRINxxx.$(PRODUCT_NAME:rfc1034identifier)"; 518 | PRODUCT_NAME = "$(TARGET_NAME)"; 519 | SWIFT_VERSION = 5.0; 520 | }; 521 | name = Release; 522 | }; 523 | 9170B0371B75A11B002BE0A7 /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 527 | BUNDLE_LOADER = "$(TEST_HOST)"; 528 | FRAMEWORK_SEARCH_PATHS = ( 529 | "$(SDKROOT)/Developer/Library/Frameworks", 530 | "$(inherited)", 531 | ); 532 | GCC_PREPROCESSOR_DEFINITIONS = ( 533 | "DEBUG=1", 534 | "$(inherited)", 535 | ); 536 | INFOPLIST_FILE = "ARNZoomImageTransitionTests/Supporting Files/Info.plist"; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 538 | PRODUCT_BUNDLE_IDENTIFIER = "xxxAIRINxxx.$(PRODUCT_NAME:rfc1034identifier)"; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | SWIFT_VERSION = 5.0; 541 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ARNZoomImageTransition.app/ARNZoomImageTransition"; 542 | }; 543 | name = Debug; 544 | }; 545 | 9170B0381B75A11B002BE0A7 /* Release */ = { 546 | isa = XCBuildConfiguration; 547 | buildSettings = { 548 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 549 | BUNDLE_LOADER = "$(TEST_HOST)"; 550 | FRAMEWORK_SEARCH_PATHS = ( 551 | "$(SDKROOT)/Developer/Library/Frameworks", 552 | "$(inherited)", 553 | ); 554 | INFOPLIST_FILE = "ARNZoomImageTransitionTests/Supporting Files/Info.plist"; 555 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 556 | PRODUCT_BUNDLE_IDENTIFIER = "xxxAIRINxxx.$(PRODUCT_NAME:rfc1034identifier)"; 557 | PRODUCT_NAME = "$(TARGET_NAME)"; 558 | SWIFT_VERSION = 5.0; 559 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ARNZoomImageTransition.app/ARNZoomImageTransition"; 560 | }; 561 | name = Release; 562 | }; 563 | /* End XCBuildConfiguration section */ 564 | 565 | /* Begin XCConfigurationList section */ 566 | 9170B00F1B75A11B002BE0A7 /* Build configuration list for PBXProject "ARNZoomImageTransition" */ = { 567 | isa = XCConfigurationList; 568 | buildConfigurations = ( 569 | 9170B0311B75A11B002BE0A7 /* Debug */, 570 | 9170B0321B75A11B002BE0A7 /* Release */, 571 | ); 572 | defaultConfigurationIsVisible = 0; 573 | defaultConfigurationName = Release; 574 | }; 575 | 9170B0331B75A11B002BE0A7 /* Build configuration list for PBXNativeTarget "ARNZoomImageTransition" */ = { 576 | isa = XCConfigurationList; 577 | buildConfigurations = ( 578 | 9170B0341B75A11B002BE0A7 /* Debug */, 579 | 9170B0351B75A11B002BE0A7 /* Release */, 580 | ); 581 | defaultConfigurationIsVisible = 0; 582 | defaultConfigurationName = Release; 583 | }; 584 | 9170B0361B75A11B002BE0A7 /* Build configuration list for PBXNativeTarget "ARNZoomImageTransitionTests" */ = { 585 | isa = XCConfigurationList; 586 | buildConfigurations = ( 587 | 9170B0371B75A11B002BE0A7 /* Debug */, 588 | 9170B0381B75A11B002BE0A7 /* Release */, 589 | ); 590 | defaultConfigurationIsVisible = 0; 591 | defaultConfigurationName = Release; 592 | }; 593 | /* End XCConfigurationList section */ 594 | }; 595 | rootObject = 9170B00C1B75A11B002BE0A7 /* Project object */; 596 | } 597 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Animation/ImageZoomAnimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageZoomAnimation.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2018/05/02. 6 | // Copyright © 2018 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import ARNTransitionAnimator 12 | 13 | protocol ImageTransitionZoomable: class { 14 | 15 | func createTransitionImageView() -> UIImageView 16 | 17 | // Present, Push 18 | 19 | func presentationBeforeAction() 20 | 21 | func presentationAnimationAction(percentComplete: CGFloat) 22 | 23 | func presentationCancelAnimationAction() 24 | 25 | func presentationCompletionAction(didComplete: Bool) 26 | 27 | // Dismiss, Pop 28 | 29 | func dismissalBeforeAction() 30 | 31 | func dismissalAnimationAction(percentComplete: CGFloat) 32 | 33 | func dismissalCancelAnimationAction() 34 | 35 | func dismissalCompletionAction(didComplete: Bool) 36 | } 37 | 38 | extension ImageZoomAnimationVC { 39 | 40 | @objc func presentationBeforeAction() {} 41 | 42 | @objc func presentationAnimationAction(percentComplete: CGFloat) {} 43 | 44 | @objc func presentationCancelAnimationAction() {} 45 | 46 | @objc func presentationCompletionAction(didComplete: Bool) {} 47 | 48 | @objc func dismissalBeforeAction() {} 49 | 50 | @objc func dismissalAnimationAction(percentComplete: CGFloat) {} 51 | 52 | @objc func dismissalCancelAnimationAction() {} 53 | 54 | @objc func dismissalCompletionAction(didComplete: Bool) {} 55 | } 56 | 57 | class ImageZoomAnimationVC: UIViewController, ImageTransitionZoomable { 58 | 59 | func createTransitionImageView() -> UIImageView { return UIImageView() } 60 | } 61 | 62 | final class ImageZoomAnimation : TransitionAnimatable where T : ImageTransitionZoomable { 63 | 64 | fileprivate weak var rootVC: T! 65 | fileprivate weak var modalVC: T! 66 | fileprivate weak var rootNavigation: UINavigationController? 67 | 68 | var completion: ((Bool) -> Void)? 69 | 70 | fileprivate var sourceImageView: UIImageView? 71 | fileprivate var destinationImageView: UIImageView? 72 | 73 | fileprivate var sourceFrame: CGRect = CGRect.zero 74 | fileprivate var destFrame: CGRect = CGRect.zero 75 | 76 | deinit { 77 | print("deinit ImageZoomAnimation") 78 | } 79 | 80 | init(rootVC: T, modalVC: T, rootNavigation: UINavigationController? = nil) { 81 | self.rootVC = rootVC 82 | self.modalVC = modalVC 83 | self.rootNavigation = rootNavigation 84 | } 85 | 86 | func prepareContainer(_ transitionType: TransitionType, containerView: UIView, from fromVC: UIViewController, to toVC: UIViewController) { 87 | if transitionType.isPresenting { 88 | containerView.addSubview(toVC.view) 89 | } else { 90 | if let v = self.rootNavigation?.view { 91 | containerView.addSubview(v) 92 | } else { 93 | containerView.addSubview(toVC.view) 94 | } 95 | containerView.addSubview(fromVC.view) 96 | } 97 | fromVC.view.setNeedsLayout() 98 | fromVC.view.layoutIfNeeded() 99 | toVC.view.setNeedsLayout() 100 | toVC.view.layoutIfNeeded() 101 | } 102 | 103 | func willAnimation(_ transitionType: TransitionType, containerView: UIView) { 104 | if transitionType.isPresenting { 105 | self.sourceImageView = rootVC.createTransitionImageView() 106 | self.destinationImageView = modalVC.createTransitionImageView() 107 | 108 | containerView.addSubview(sourceImageView!) 109 | 110 | rootVC.presentationBeforeAction() 111 | modalVC.presentationBeforeAction() 112 | 113 | modalVC.view.alpha = 0.0 114 | } else { 115 | self.sourceImageView = modalVC.createTransitionImageView() 116 | self.destinationImageView = rootVC.createTransitionImageView() 117 | 118 | self.sourceFrame = self.sourceImageView!.frame 119 | self.destFrame = self.destinationImageView!.frame 120 | 121 | containerView.addSubview(sourceImageView!) 122 | 123 | rootVC.dismissalBeforeAction() 124 | modalVC.dismissalBeforeAction() 125 | } 126 | } 127 | 128 | func updateAnimation(_ transitionType: TransitionType, percentComplete: CGFloat) { 129 | print(percentComplete) 130 | if transitionType.isPresenting { 131 | self.sourceImageView?.frame = self.destinationImageView!.frame 132 | 133 | self.modalVC.view.alpha = 1.0 * percentComplete 134 | 135 | self.rootVC.presentationAnimationAction(percentComplete: percentComplete) 136 | self.modalVC.presentationAnimationAction(percentComplete: percentComplete) 137 | } else { 138 | let p = 1.0 - (1.0 * percentComplete) 139 | 140 | let frame = CGRect( 141 | x: destFrame.origin.x - (destFrame.origin.x - sourceFrame.origin.x) * p, 142 | y: destFrame.origin.y - (destFrame.origin.y - sourceFrame.origin.y) * p, 143 | width: destFrame.size.width + (sourceFrame.size.width - destFrame.size.width) * p, 144 | height: destFrame.size.height + (sourceFrame.size.height - destFrame.size.height) * p 145 | ) 146 | self.sourceImageView!.frame = frame 147 | self.modalVC.view.alpha = p 148 | 149 | self.rootVC.dismissalAnimationAction(percentComplete: percentComplete) 150 | self.modalVC.dismissalAnimationAction(percentComplete: percentComplete) 151 | } 152 | } 153 | 154 | func finishAnimation(_ transitionType: TransitionType, didComplete: Bool) { 155 | self.sourceImageView?.removeFromSuperview() 156 | self.destinationImageView?.removeFromSuperview() 157 | 158 | if transitionType.isPresenting { 159 | self.rootVC.presentationCompletionAction(didComplete: didComplete) 160 | self.modalVC.presentationCompletionAction(didComplete: didComplete) 161 | } else { 162 | self.rootVC.dismissalCompletionAction(didComplete: didComplete) 163 | self.modalVC.dismissalCompletionAction(didComplete: didComplete) 164 | } 165 | self.completion?(didComplete) 166 | } 167 | } 168 | 169 | extension ImageZoomAnimation { 170 | 171 | func sourceVC() -> UIViewController { return self.rootVC } 172 | 173 | func destVC() -> UIViewController { return self.modalVC } 174 | } 175 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 17 | return true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Cell/CollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionCell.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CollectionCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var cellImageView : UIImageView! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Cell/CollectionCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Cell/TableCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableCell.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableCell: UITableViewCell { 12 | 13 | @IBOutlet weak var cellImageView : UIImageView! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Cell/TableCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Controller/DetailViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Controller/DetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DetailViewController: ImageZoomAnimationVC { 12 | 13 | @IBOutlet weak var imageView : UIImageView! 14 | 15 | deinit { 16 | print("deinit DetailViewController") 17 | } 18 | 19 | override func viewWillAppear(_ animated: Bool) { 20 | super.viewWillAppear(animated) 21 | print("DetailViewController viewWillAppear") 22 | } 23 | 24 | override func viewWillDisappear(_ animated: Bool) { 25 | super.viewWillDisappear(animated) 26 | print("DetailViewController viewWillDisappear") 27 | } 28 | 29 | // MARK: - ImageTransitionZoomable 30 | 31 | override func createTransitionImageView() -> UIImageView { 32 | let imageView = UIImageView(image: self.imageView.image) 33 | imageView.contentMode = self.imageView.contentMode 34 | imageView.clipsToBounds = true 35 | imageView.isUserInteractionEnabled = false 36 | imageView.frame = self.imageView!.frame 37 | return imageView 38 | } 39 | 40 | @objc override func presentationBeforeAction() { 41 | self.imageView.isHidden = true 42 | } 43 | 44 | @objc override func presentationCompletionAction(didComplete: Bool) { 45 | if didComplete { 46 | self.imageView.isHidden = false 47 | } 48 | } 49 | 50 | @objc override func dismissalBeforeAction() { 51 | self.imageView.isHidden = true 52 | } 53 | 54 | @objc override func dismissalCompletionAction(didComplete: Bool) { 55 | if !didComplete { 56 | self.imageView.isHidden = false 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Controller/MainViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Controller/MainViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ARNTransitionAnimator 11 | 12 | class MainViewController: ImageZoomAnimationVC, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDataSource, UITableViewDelegate { 13 | 14 | @IBOutlet weak var collectionView : UICollectionView! 15 | @IBOutlet weak var tableView : UITableView! 16 | 17 | weak var selectedImageView : UIImageView? 18 | 19 | var animator : ARNTransitionAnimator? 20 | 21 | var isModeModal : Bool = false 22 | var isModeInteractive : Bool = false 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | self.extendedLayoutIncludesOpaqueBars = false 28 | 29 | self.collectionView.register(UINib(nibName: "CollectionCell", bundle: nil), forCellWithReuseIdentifier: "CollectionCell") 30 | 31 | self.tableView.register(UINib(nibName: "TableCell", bundle: nil), forCellReuseIdentifier: "TableCell") 32 | 33 | self.updateNavigationItem() 34 | } 35 | 36 | override func viewWillAppear(_ animated: Bool) { 37 | super.viewWillAppear(animated) 38 | print("MainViewController viewWillAppear") 39 | } 40 | 41 | override func viewWillDisappear(_ animated: Bool) { 42 | super.viewWillDisappear(animated) 43 | print("MainViewController viewWillDisappear") 44 | } 45 | 46 | func updateNavigationItem() { 47 | if isModeModal { 48 | self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Modal", style: .done, target: self, action: #selector(self.modePush)) 49 | } else { 50 | self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Push", style: .done, target: self, action: #selector(self.modeModal)) 51 | } 52 | 53 | if isModeInteractive { 54 | self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Interactive", style: .done, target: self, action: #selector(self.modeNormal)) 55 | } else { 56 | self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Normal", style: .done, target: self, action: #selector(self.modeInteractive)) 57 | } 58 | } 59 | 60 | @objc func modePush() { 61 | self.isModeModal = false 62 | self.updateNavigationItem() 63 | } 64 | 65 | @objc func modeModal() { 66 | self.isModeModal = true 67 | self.updateNavigationItem() 68 | } 69 | 70 | @objc func modeInteractive() { 71 | self.isModeInteractive = true 72 | self.updateNavigationItem() 73 | } 74 | 75 | @objc func modeNormal() { 76 | self.isModeInteractive = false 77 | self.updateNavigationItem() 78 | } 79 | 80 | func handleTransition() { 81 | if isModeInteractive { 82 | self.showInteractive() 83 | } else { 84 | if isModeModal { 85 | let storyboard = UIStoryboard(name: "ModalViewController", bundle: nil) 86 | let controller = storyboard.instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 87 | 88 | let animation = ImageZoomAnimation(rootVC: self, modalVC: controller, rootNavigation: self.navigationController) 89 | let animator = ARNTransitionAnimator(duration: 0.5, animation: animation) 90 | controller.transitioningDelegate = animator 91 | self.animator = animator 92 | 93 | self.present(controller, animated: true, completion: nil) 94 | } else { 95 | let storyboard = UIStoryboard(name: "DetailViewController", bundle: nil) 96 | let controller = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController 97 | 98 | let animation = ImageZoomAnimation(rootVC: self, modalVC: controller) 99 | let animator = ARNTransitionAnimator(duration: 0.5, animation: animation) 100 | self.navigationController?.delegate = animator 101 | self.animator = animator 102 | 103 | self.navigationController?.pushViewController(controller, animated: true) 104 | } 105 | } 106 | } 107 | 108 | func showInteractive() { 109 | if isModeModal { 110 | let storyboard = UIStoryboard(name: "ModalViewController", bundle: nil) 111 | let controller = storyboard.instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController 112 | 113 | let animation = ImageZoomAnimation(rootVC: self, modalVC: controller, rootNavigation: self.navigationController) 114 | let animator = ARNTransitionAnimator(duration: 0.5, animation: animation) 115 | 116 | let gestureHandler = TransitionGestureHandler(targetView: controller.view, direction: .bottom) 117 | animator.registerInteractiveTransitioning(.dismiss, gestureHandler: gestureHandler) 118 | 119 | controller.transitioningDelegate = animator 120 | self.animator = animator 121 | 122 | self.present(controller, animated: true, completion: nil) 123 | } else { 124 | let storyboard = UIStoryboard(name: "DetailViewController", bundle: nil) 125 | let controller = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController 126 | 127 | let animation = ImageZoomAnimation(rootVC: self, modalVC: controller) 128 | let animator = ARNTransitionAnimator(duration: 0.5, animation: animation) 129 | 130 | let gestureHandler = TransitionGestureHandler(targetView: controller.view, direction: .bottom) 131 | animator.registerInteractiveTransitioning(.pop, gestureHandler: gestureHandler) 132 | 133 | self.navigationController?.delegate = animator 134 | self.animator = animator 135 | 136 | self.navigationController?.pushViewController(controller, animated: true) 137 | } 138 | } 139 | 140 | // MARK: - ImageTransitionZoomable 141 | 142 | override func createTransitionImageView() -> UIImageView { 143 | let imageView = UIImageView(image: self.selectedImageView!.image) 144 | imageView.contentMode = self.selectedImageView!.contentMode 145 | imageView.clipsToBounds = true 146 | imageView.isUserInteractionEnabled = false 147 | imageView.frame = self.selectedImageView!.convert(self.selectedImageView!.frame, to: self.view) 148 | 149 | return imageView 150 | } 151 | 152 | @objc override func presentationBeforeAction() { 153 | self.selectedImageView?.isHidden = true 154 | } 155 | 156 | override func presentationCompletionAction(didComplete: Bool) { 157 | self.selectedImageView?.isHidden = true 158 | } 159 | 160 | @objc override func dismissalBeforeAction() { 161 | self.selectedImageView?.isHidden = true 162 | } 163 | 164 | override func dismissalCompletionAction(didComplete: Bool) { 165 | self.selectedImageView?.isHidden = false 166 | } 167 | 168 | // MARK: - UICollectionViewDataSource 169 | 170 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 171 | return 20 172 | } 173 | 174 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 175 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionCell 176 | return cell 177 | } 178 | 179 | // MARK: - UICollectionViewDelegate 180 | 181 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 182 | let cell = collectionView.cellForItem(at: indexPath) as! CollectionCell 183 | self.selectedImageView = cell.cellImageView 184 | 185 | self.handleTransition() 186 | } 187 | 188 | // MARK: - UITableViewDataSource 189 | 190 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 191 | return 20 192 | } 193 | 194 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 195 | let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell 196 | return cell 197 | } 198 | 199 | // MARK: - UITableViewDelegate 200 | 201 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 202 | return 44.0 203 | } 204 | 205 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 206 | tableView.deselectRow(at: indexPath, animated: true) 207 | 208 | let cell = tableView.cellForRow(at: indexPath) as! TableCell 209 | self.selectedImageView = cell.cellImageView 210 | 211 | self.handleTransition() 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Controller/ModalViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 28 | 29 | 30 | 31 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Controller/ModalViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ModalViewController.swift 3 | // ARNZoomImageTransition 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ModalViewController: ImageZoomAnimationVC { 12 | 13 | @IBOutlet weak var imageView : UIImageView! 14 | @IBOutlet weak var closeButton : UIButton! 15 | 16 | @IBAction func tapCloseButton() { 17 | self.dismiss(animated: true, completion: nil) 18 | } 19 | 20 | deinit { 21 | print("deinit ModalViewController") 22 | } 23 | 24 | override func viewWillAppear(_ animated: Bool) { 25 | super.viewWillAppear(animated) 26 | print("ModalViewController viewWillAppear") 27 | } 28 | 29 | override func viewWillDisappear(_ animated: Bool) { 30 | super.viewWillDisappear(animated) 31 | print("ModalViewController viewWillDisappear") 32 | } 33 | 34 | // MARK: - ImageTransitionZoomable 35 | 36 | override func createTransitionImageView() -> UIImageView { 37 | let imageView = UIImageView(image: self.imageView.image) 38 | imageView.contentMode = self.imageView.contentMode 39 | imageView.clipsToBounds = true 40 | imageView.isUserInteractionEnabled = false 41 | imageView.frame = self.imageView!.frame 42 | return imageView 43 | } 44 | 45 | override func presentationBeforeAction() { 46 | self.imageView.isHidden = true 47 | } 48 | 49 | override func presentationCompletionAction(didComplete: Bool) { 50 | self.imageView.isHidden = false 51 | } 52 | 53 | override func dismissalBeforeAction() { 54 | self.imageView.isHidden = true 55 | } 56 | 57 | override func dismissalCompletionAction(didComplete: Bool) { 58 | if !didComplete { 59 | self.imageView.isHidden = false 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | MainViewController 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransition/mos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxAIRINxxx/ARNZoomImageTransition/c56b7437d62c2fb0f1361f7f71fecbad3f438cc8/ARNZoomImageTransition/ARNZoomImageTransition/mos.jpg -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransitionTests/ARNZoomImageTransitionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ARNZoomImageTransitionTests.swift 3 | // ARNZoomImageTransitionTests 4 | // 5 | // Created by xxxAIRINxxx on 2015/08/08. 6 | // Copyright (c) 2015 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class ARNZoomImageTransitionTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/ARNZoomImageTransitionTests/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/Podfile: -------------------------------------------------------------------------------- 1 | project 'ARNZoomImageTransition.xcodeproj' 2 | 3 | platform :ios, '10.0' 4 | use_frameworks! 5 | 6 | target 'ARNZoomImageTransition' do 7 | 8 | pod 'ARNTransitionAnimator' 9 | 10 | end 11 | -------------------------------------------------------------------------------- /ARNZoomImageTransition/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ARNTransitionAnimator (3.2.0) 3 | 4 | DEPENDENCIES: 5 | - ARNTransitionAnimator 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - ARNTransitionAnimator 10 | 11 | SPEC CHECKSUMS: 12 | ARNTransitionAnimator: 6fea1fe318b251abfd3cbd06d91215deb374ae40 13 | 14 | PODFILE CHECKSUM: 0ae87dff851215849690e10df7efbf4ccb05cb81 15 | 16 | COCOAPODS: 1.6.1 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Airin 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ARNZoomImageTransition 2 | 3 | [![Swift 5.0](https://img.shields.io/badge/Swift-5.0-orange.svg?style=flat)](https://developer.apple.com/swift/) 4 | [![Platforms iOS](https://img.shields.io/badge/Platforms-iOS-lightgray.svg?style=flat)](https://developer.apple.com/swift/) 5 | [![Xcode 10.2+](https://img.shields.io/badge/Xcode-10.2+-blue.svg?style=flat)](https://developer.apple.com/swift/) 6 | 7 | ![capture](capture.gif "capture") 8 | 9 | Custom image zooming animation transition. & interactive transition. written in Swift. 10 | 11 | ## Demo 12 | 13 | [See demo on Appetize.io](https://appetize.io/app/7z0pzg1ntzbyef47e0rjpmck2g?device=iphone5s&scale=75&orientation=portrait&osVersion=9.2) 14 | 15 | ## Using Transition Animator 16 | 17 | This sample have created as a showcase of ARNTransitionAnimator. 18 | 19 | [ARNTransitionAnimator](https://github.com/xxxAIRINxxx/ARNTransitionAnimator) 20 | 21 | 22 | ## Requirements 23 | 24 | * iOS 10.0+ 25 | * Swift 5.0+ 26 | * Xcode 10.2+ 27 | * CocoaPods 1.6.1+ 28 | 29 | ## License 30 | 31 | MIT license. See the LICENSE file for more info. 32 | -------------------------------------------------------------------------------- /capture.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxAIRINxxx/ARNZoomImageTransition/c56b7437d62c2fb0f1361f7f71fecbad3f438cc8/capture.gif --------------------------------------------------------------------------------