├── .gitignore ├── .swift-version ├── LICENSE ├── MusicAppTransition.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── MusicAppTransition.xcscheme ├── MusicAppTransition.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── MusicAppTransition ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── ContentsViewController.swift ├── Info.plist ├── MusicCell.xib ├── PlayerViewController.swift ├── TopViewController.swift └── tia.jpg ├── Podfile ├── Podfile.lock ├── README.md └── capture.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/xcode,swift 2 | 3 | # Mac OS X 4 | .DS_Store 5 | 6 | ### Xcode ### 7 | # Xcode 8 | # 9 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 10 | 11 | ## Build generated 12 | build/ 13 | DerivedData/ 14 | 15 | ## Various settings 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | #xcuserdata/ 25 | 26 | ## Other 27 | *.moved-aside 28 | *.xccheckout 29 | *.xcscmblueprint 30 | 31 | 32 | ### Swift ### 33 | # Xcode 34 | # 35 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 36 | 37 | ## Build generated 38 | build/ 39 | DerivedData/ 40 | 41 | ## Various settings 42 | *.pbxuser 43 | !default.pbxuser 44 | *.mode1v3 45 | !default.mode1v3 46 | *.mode2v3 47 | !default.mode2v3 48 | *.perspectivev3 49 | !default.perspectivev3 50 | xcuserdata/ 51 | 52 | ## Other 53 | *.moved-aside 54 | *.xcuserstate 55 | 56 | ## Obj-C/Swift specific 57 | *.hmap 58 | *.ipa 59 | *.dSYM.zip 60 | *.dSYM 61 | 62 | ## Playgrounds 63 | timeline.xctimeline 64 | playground.xcworkspace 65 | 66 | # Swift Package Manager 67 | # 68 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 69 | # Packages/ 70 | .build/ 71 | 72 | # CocoaPods 73 | # 74 | # We recommend against adding the Pods directory to your .gitignore. However 75 | # you should judge for yourself, the pros and cons are mentioned at: 76 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 77 | # 78 | Pods/ 79 | 80 | # Carthage 81 | # 82 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 83 | # Carthage/Checkouts 84 | 85 | # Carthage/Build 86 | 87 | # fastlane 88 | # 89 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 90 | # screenshots whenever they are needed. 91 | # For more information about the recommended setup visit: 92 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 93 | 94 | fastlane/report.xml 95 | fastlane/Preview.html 96 | fastlane/screenshots 97 | fastlane/test_output 98 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 xxxAIRINxxx 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 | -------------------------------------------------------------------------------- /MusicAppTransition.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 912986CB21284988006706E1 /* tia.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 912986CA21284988006706E1 /* tia.jpg */; }; 11 | 9172EE61211AE1180044F6D3 /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9172EE60211AE1180044F6D3 /* PlayerViewController.swift */; }; 12 | 9172EE63211AE1570044F6D3 /* TopViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9172EE62211AE1570044F6D3 /* TopViewController.swift */; }; 13 | 9189E4812127FE8900FB3DAF /* MusicCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9189E4802127FE8900FB3DAF /* MusicCell.xib */; }; 14 | 9194016721254F86002967C5 /* ContentsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9194016621254F86002967C5 /* ContentsViewController.swift */; }; 15 | 91FBFB271C5904EA0064E23C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91FBFB261C5904EA0064E23C /* AppDelegate.swift */; }; 16 | 91FBFB2C1C5904EA0064E23C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 91FBFB2A1C5904EA0064E23C /* Main.storyboard */; }; 17 | 91FBFB2E1C5904EA0064E23C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 91FBFB2D1C5904EA0064E23C /* Assets.xcassets */; }; 18 | 91FBFB311C5904EA0064E23C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 91FBFB2F1C5904EA0064E23C /* LaunchScreen.storyboard */; }; 19 | F3F84E14849EDBFB7D45B886 /* Pods_MusicAppTransition.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B6C512B1FB6291A53BA4B9A /* Pods_MusicAppTransition.framework */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | 916DFDF621104A4E009B365C /* Embed Frameworks */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 10; 28 | files = ( 29 | ); 30 | name = "Embed Frameworks"; 31 | runOnlyForDeploymentPostprocessing = 0; 32 | }; 33 | /* End PBXCopyFilesBuildPhase section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 6B6C512B1FB6291A53BA4B9A /* Pods_MusicAppTransition.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MusicAppTransition.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 912986CA21284988006706E1 /* tia.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = tia.jpg; sourceTree = ""; }; 38 | 9172EE60211AE1180044F6D3 /* PlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerViewController.swift; sourceTree = ""; }; 39 | 9172EE62211AE1570044F6D3 /* TopViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopViewController.swift; sourceTree = ""; }; 40 | 9189E4802127FE8900FB3DAF /* MusicCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicCell.xib; sourceTree = ""; }; 41 | 9194016621254F86002967C5 /* ContentsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentsViewController.swift; sourceTree = ""; }; 42 | 91FBFB231C5904E90064E23C /* MusicAppTransition.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MusicAppTransition.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | 91FBFB261C5904EA0064E23C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 44 | 91FBFB2B1C5904EA0064E23C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 91FBFB2D1C5904EA0064E23C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 91FBFB301C5904EA0064E23C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 91FBFB321C5904EB0064E23C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | B26ABC347AE4FE2B0F0564CC /* Pods-MusicAppTransition.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MusicAppTransition.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MusicAppTransition/Pods-MusicAppTransition.debug.xcconfig"; sourceTree = ""; }; 49 | DF1E9C309FAFFF585BA980DE /* Pods-MusicAppTransition.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MusicAppTransition.release.xcconfig"; path = "Pods/Target Support Files/Pods-MusicAppTransition/Pods-MusicAppTransition.release.xcconfig"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 91FBFB201C5904E90064E23C /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | F3F84E14849EDBFB7D45B886 /* Pods_MusicAppTransition.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 914D99842112AE3A00FE7FED /* Frameworks */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 6B6C512B1FB6291A53BA4B9A /* Pods_MusicAppTransition.framework */, 68 | ); 69 | name = Frameworks; 70 | sourceTree = ""; 71 | }; 72 | 91FBFB1A1C5904E90064E23C = { 73 | isa = PBXGroup; 74 | children = ( 75 | 91FBFB251C5904EA0064E23C /* MusicAppTransition */, 76 | 914D99842112AE3A00FE7FED /* Frameworks */, 77 | DDC4478E16382C5645B1A4F3 /* Pods */, 78 | ); 79 | sourceTree = ""; 80 | }; 81 | 91FBFB241C5904E90064E23C /* Products */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 91FBFB231C5904E90064E23C /* MusicAppTransition.app */, 85 | ); 86 | name = Products; 87 | path = ..; 88 | sourceTree = ""; 89 | }; 90 | 91FBFB251C5904EA0064E23C /* MusicAppTransition */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 91FBFB261C5904EA0064E23C /* AppDelegate.swift */, 94 | 9172EE62211AE1570044F6D3 /* TopViewController.swift */, 95 | 9172EE60211AE1180044F6D3 /* PlayerViewController.swift */, 96 | 9194016621254F86002967C5 /* ContentsViewController.swift */, 97 | 9189E4802127FE8900FB3DAF /* MusicCell.xib */, 98 | 91FBFB2A1C5904EA0064E23C /* Main.storyboard */, 99 | 91FBFB2D1C5904EA0064E23C /* Assets.xcassets */, 100 | 91FBFB2F1C5904EA0064E23C /* LaunchScreen.storyboard */, 101 | 91FBFB321C5904EB0064E23C /* Info.plist */, 102 | 912986CA21284988006706E1 /* tia.jpg */, 103 | 91FBFB241C5904E90064E23C /* Products */, 104 | ); 105 | path = MusicAppTransition; 106 | sourceTree = ""; 107 | }; 108 | DDC4478E16382C5645B1A4F3 /* Pods */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | B26ABC347AE4FE2B0F0564CC /* Pods-MusicAppTransition.debug.xcconfig */, 112 | DF1E9C309FAFFF585BA980DE /* Pods-MusicAppTransition.release.xcconfig */, 113 | ); 114 | name = Pods; 115 | sourceTree = ""; 116 | }; 117 | /* End PBXGroup section */ 118 | 119 | /* Begin PBXNativeTarget section */ 120 | 91FBFB221C5904E90064E23C /* MusicAppTransition */ = { 121 | isa = PBXNativeTarget; 122 | buildConfigurationList = 91FBFB351C5904EB0064E23C /* Build configuration list for PBXNativeTarget "MusicAppTransition" */; 123 | buildPhases = ( 124 | 6B0AB198EF56A1E5568CFEA5 /* [CP] Check Pods Manifest.lock */, 125 | 91FBFB1F1C5904E90064E23C /* Sources */, 126 | 91FBFB201C5904E90064E23C /* Frameworks */, 127 | 91FBFB211C5904E90064E23C /* Resources */, 128 | 916DFDF621104A4E009B365C /* Embed Frameworks */, 129 | 48BA68008FE5DF03363EE1BF /* [CP] Embed Pods Frameworks */, 130 | ); 131 | buildRules = ( 132 | ); 133 | dependencies = ( 134 | ); 135 | name = MusicAppTransition; 136 | productName = Demo; 137 | productReference = 91FBFB231C5904E90064E23C /* MusicAppTransition.app */; 138 | productType = "com.apple.product-type.application"; 139 | }; 140 | /* End PBXNativeTarget section */ 141 | 142 | /* Begin PBXProject section */ 143 | 91FBFB1B1C5904E90064E23C /* Project object */ = { 144 | isa = PBXProject; 145 | attributes = { 146 | LastSwiftUpdateCheck = 0720; 147 | LastUpgradeCheck = 1020; 148 | ORGANIZATIONNAME = xxxAIRINxxx; 149 | TargetAttributes = { 150 | 91FBFB221C5904E90064E23C = { 151 | CreatedOnToolsVersion = 7.2; 152 | DevelopmentTeam = P599PJHMNF; 153 | DevelopmentTeamName = "TAKASHI YOSHINAGA"; 154 | LastSwiftMigration = 1000; 155 | }; 156 | }; 157 | }; 158 | buildConfigurationList = 91FBFB1E1C5904E90064E23C /* Build configuration list for PBXProject "MusicAppTransition" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = en; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | en, 164 | Base, 165 | ); 166 | mainGroup = 91FBFB1A1C5904E90064E23C; 167 | productRefGroup = 91FBFB241C5904E90064E23C /* Products */; 168 | projectDirPath = ""; 169 | projectRoot = ""; 170 | targets = ( 171 | 91FBFB221C5904E90064E23C /* MusicAppTransition */, 172 | ); 173 | }; 174 | /* End PBXProject section */ 175 | 176 | /* Begin PBXResourcesBuildPhase section */ 177 | 91FBFB211C5904E90064E23C /* Resources */ = { 178 | isa = PBXResourcesBuildPhase; 179 | buildActionMask = 2147483647; 180 | files = ( 181 | 912986CB21284988006706E1 /* tia.jpg in Resources */, 182 | 9189E4812127FE8900FB3DAF /* MusicCell.xib in Resources */, 183 | 91FBFB311C5904EA0064E23C /* LaunchScreen.storyboard in Resources */, 184 | 91FBFB2E1C5904EA0064E23C /* Assets.xcassets in Resources */, 185 | 91FBFB2C1C5904EA0064E23C /* Main.storyboard in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXShellScriptBuildPhase section */ 192 | 48BA68008FE5DF03363EE1BF /* [CP] Embed Pods Frameworks */ = { 193 | isa = PBXShellScriptBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | ); 197 | inputPaths = ( 198 | "${PODS_ROOT}/Target Support Files/Pods-MusicAppTransition/Pods-MusicAppTransition-frameworks.sh", 199 | "${BUILT_PRODUCTS_DIR}/Movin/Movin.framework", 200 | ); 201 | name = "[CP] Embed Pods Frameworks"; 202 | outputPaths = ( 203 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Movin.framework", 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | shellPath = /bin/sh; 207 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MusicAppTransition/Pods-MusicAppTransition-frameworks.sh\"\n"; 208 | showEnvVarsInLog = 0; 209 | }; 210 | 6B0AB198EF56A1E5568CFEA5 /* [CP] Check Pods Manifest.lock */ = { 211 | isa = PBXShellScriptBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | inputPaths = ( 216 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 217 | "${PODS_ROOT}/Manifest.lock", 218 | ); 219 | name = "[CP] Check Pods Manifest.lock"; 220 | outputPaths = ( 221 | "$(DERIVED_FILE_DIR)/Pods-MusicAppTransition-checkManifestLockResult.txt", 222 | ); 223 | runOnlyForDeploymentPostprocessing = 0; 224 | shellPath = /bin/sh; 225 | 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"; 226 | showEnvVarsInLog = 0; 227 | }; 228 | /* End PBXShellScriptBuildPhase section */ 229 | 230 | /* Begin PBXSourcesBuildPhase section */ 231 | 91FBFB1F1C5904E90064E23C /* Sources */ = { 232 | isa = PBXSourcesBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | 9194016721254F86002967C5 /* ContentsViewController.swift in Sources */, 236 | 9172EE63211AE1570044F6D3 /* TopViewController.swift in Sources */, 237 | 9172EE61211AE1180044F6D3 /* PlayerViewController.swift in Sources */, 238 | 91FBFB271C5904EA0064E23C /* AppDelegate.swift in Sources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | /* End PBXSourcesBuildPhase section */ 243 | 244 | /* Begin PBXVariantGroup section */ 245 | 91FBFB2A1C5904EA0064E23C /* Main.storyboard */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | 91FBFB2B1C5904EA0064E23C /* Base */, 249 | ); 250 | name = Main.storyboard; 251 | sourceTree = ""; 252 | }; 253 | 91FBFB2F1C5904EA0064E23C /* LaunchScreen.storyboard */ = { 254 | isa = PBXVariantGroup; 255 | children = ( 256 | 91FBFB301C5904EA0064E23C /* Base */, 257 | ); 258 | name = LaunchScreen.storyboard; 259 | sourceTree = ""; 260 | }; 261 | /* End PBXVariantGroup section */ 262 | 263 | /* Begin XCBuildConfiguration section */ 264 | 91FBFB331C5904EB0064E23C /* Debug */ = { 265 | isa = XCBuildConfiguration; 266 | buildSettings = { 267 | ALWAYS_SEARCH_USER_PATHS = NO; 268 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 270 | CLANG_CXX_LIBRARY = "libc++"; 271 | CLANG_ENABLE_MODULES = YES; 272 | CLANG_ENABLE_OBJC_ARC = YES; 273 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 274 | CLANG_WARN_BOOL_CONVERSION = YES; 275 | CLANG_WARN_COMMA = YES; 276 | CLANG_WARN_CONSTANT_CONVERSION = YES; 277 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 279 | CLANG_WARN_EMPTY_BODY = YES; 280 | CLANG_WARN_ENUM_CONVERSION = YES; 281 | CLANG_WARN_INFINITE_RECURSION = YES; 282 | CLANG_WARN_INT_CONVERSION = YES; 283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 284 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 285 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 287 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 288 | CLANG_WARN_STRICT_PROTOTYPES = YES; 289 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 290 | CLANG_WARN_UNREACHABLE_CODE = YES; 291 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 292 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 293 | COPY_PHASE_STRIP = NO; 294 | DEBUG_INFORMATION_FORMAT = dwarf; 295 | ENABLE_STRICT_OBJC_MSGSEND = YES; 296 | ENABLE_TESTABILITY = YES; 297 | GCC_C_LANGUAGE_STANDARD = gnu99; 298 | GCC_DYNAMIC_NO_PIC = NO; 299 | GCC_NO_COMMON_BLOCKS = YES; 300 | GCC_OPTIMIZATION_LEVEL = 0; 301 | GCC_PREPROCESSOR_DEFINITIONS = ( 302 | "DEBUG=1", 303 | "$(inherited)", 304 | ); 305 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 306 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 307 | GCC_WARN_UNDECLARED_SELECTOR = YES; 308 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 309 | GCC_WARN_UNUSED_FUNCTION = YES; 310 | GCC_WARN_UNUSED_VARIABLE = YES; 311 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 312 | MTL_ENABLE_DEBUG_INFO = YES; 313 | ONLY_ACTIVE_ARCH = YES; 314 | SDKROOT = iphoneos; 315 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 316 | }; 317 | name = Debug; 318 | }; 319 | 91FBFB341C5904EB0064E23C /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ALWAYS_SEARCH_USER_PATHS = NO; 323 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 324 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 325 | CLANG_CXX_LIBRARY = "libc++"; 326 | CLANG_ENABLE_MODULES = YES; 327 | CLANG_ENABLE_OBJC_ARC = YES; 328 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 329 | CLANG_WARN_BOOL_CONVERSION = YES; 330 | CLANG_WARN_COMMA = YES; 331 | CLANG_WARN_CONSTANT_CONVERSION = YES; 332 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 333 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 334 | CLANG_WARN_EMPTY_BODY = YES; 335 | CLANG_WARN_ENUM_CONVERSION = YES; 336 | CLANG_WARN_INFINITE_RECURSION = YES; 337 | CLANG_WARN_INT_CONVERSION = YES; 338 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 339 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 340 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 341 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 342 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 343 | CLANG_WARN_STRICT_PROTOTYPES = YES; 344 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 345 | CLANG_WARN_UNREACHABLE_CODE = YES; 346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 347 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 348 | COPY_PHASE_STRIP = NO; 349 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 350 | ENABLE_NS_ASSERTIONS = NO; 351 | ENABLE_STRICT_OBJC_MSGSEND = YES; 352 | GCC_C_LANGUAGE_STANDARD = gnu99; 353 | GCC_NO_COMMON_BLOCKS = YES; 354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 356 | GCC_WARN_UNDECLARED_SELECTOR = YES; 357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 358 | GCC_WARN_UNUSED_FUNCTION = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 361 | MTL_ENABLE_DEBUG_INFO = NO; 362 | SDKROOT = iphoneos; 363 | VALIDATE_PRODUCT = YES; 364 | }; 365 | name = Release; 366 | }; 367 | 91FBFB361C5904EB0064E23C /* Debug */ = { 368 | isa = XCBuildConfiguration; 369 | baseConfigurationReference = B26ABC347AE4FE2B0F0564CC /* Pods-MusicAppTransition.debug.xcconfig */; 370 | buildSettings = { 371 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 372 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 373 | CODE_SIGN_IDENTITY = "iPhone Developer"; 374 | DEVELOPMENT_TEAM = P599PJHMNF; 375 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 376 | INFOPLIST_FILE = "$(SRCROOT)/MusicAppTransition/Info.plist"; 377 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 378 | PRODUCT_BUNDLE_IDENTIFIER = xxxAIRINxxx.MusicAppTransition; 379 | PRODUCT_NAME = "$(TARGET_NAME)"; 380 | SWIFT_VERSION = 5.0; 381 | }; 382 | name = Debug; 383 | }; 384 | 91FBFB371C5904EB0064E23C /* Release */ = { 385 | isa = XCBuildConfiguration; 386 | baseConfigurationReference = DF1E9C309FAFFF585BA980DE /* Pods-MusicAppTransition.release.xcconfig */; 387 | buildSettings = { 388 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 390 | CODE_SIGN_IDENTITY = "iPhone Developer"; 391 | DEVELOPMENT_TEAM = P599PJHMNF; 392 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 393 | INFOPLIST_FILE = "$(SRCROOT)/MusicAppTransition/Info.plist"; 394 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 395 | PRODUCT_BUNDLE_IDENTIFIER = xxxAIRINxxx.MusicAppTransition; 396 | PRODUCT_NAME = "$(TARGET_NAME)"; 397 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 398 | SWIFT_VERSION = 5.0; 399 | }; 400 | name = Release; 401 | }; 402 | /* End XCBuildConfiguration section */ 403 | 404 | /* Begin XCConfigurationList section */ 405 | 91FBFB1E1C5904E90064E23C /* Build configuration list for PBXProject "MusicAppTransition" */ = { 406 | isa = XCConfigurationList; 407 | buildConfigurations = ( 408 | 91FBFB331C5904EB0064E23C /* Debug */, 409 | 91FBFB341C5904EB0064E23C /* Release */, 410 | ); 411 | defaultConfigurationIsVisible = 0; 412 | defaultConfigurationName = Release; 413 | }; 414 | 91FBFB351C5904EB0064E23C /* Build configuration list for PBXNativeTarget "MusicAppTransition" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | 91FBFB361C5904EB0064E23C /* Debug */, 418 | 91FBFB371C5904EB0064E23C /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Release; 422 | }; 423 | /* End XCConfigurationList section */ 424 | }; 425 | rootObject = 91FBFB1B1C5904E90064E23C /* Project object */; 426 | } 427 | -------------------------------------------------------------------------------- /MusicAppTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MusicAppTransition.xcodeproj/xcshareddata/xcschemes/MusicAppTransition.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /MusicAppTransition.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /MusicAppTransition.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MusicAppTransition.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MusicAppTransition/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MusicAppTransition 4 | // 5 | // Created by xxxAIRINxxx on 2018/08/01. 6 | // Copyright © 2016 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Movin 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 18 | Movin.isDebugPrintEnabled = true 19 | return true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MusicAppTransition/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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /MusicAppTransition/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MusicAppTransition/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 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 53 | 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 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | -------------------------------------------------------------------------------- /MusicAppTransition/ContentsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentsViewController.swift 3 | // MusicAppTransition 4 | // 5 | // Created by xxxAIRINxxx on 2018/08/03. 6 | // Copyright © 2018 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class ContentsViewController: UIViewController { 12 | 13 | @IBOutlet private weak var collectionView: UICollectionView! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | self.collectionView.register(UINib(nibName: "MusicCell", bundle: nil), forCellWithReuseIdentifier: "MusicCell") 19 | 20 | if #available(iOS 11.0, *) { 21 | self.navigationController?.navigationBar.prefersLargeTitles = true 22 | self.navigationItem.largeTitleDisplayMode = .always 23 | } 24 | } 25 | } 26 | 27 | extension ContentsViewController : UICollectionViewDataSource { 28 | 29 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 30 | return 12 31 | } 32 | 33 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 34 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MusicCell", for: indexPath) as! MusicCell 35 | 36 | return cell 37 | } 38 | } 39 | 40 | extension ContentsViewController : UICollectionViewDelegateFlowLayout { 41 | 42 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 43 | let width = (collectionView.frame.width - 60) / 2 44 | return CGSize(width: width, height: width) 45 | } 46 | } 47 | 48 | final class MusicCell: UICollectionViewCell { 49 | 50 | @IBOutlet private weak var imageView: UIImageView! 51 | 52 | override func awakeFromNib() { 53 | super.awakeFromNib() 54 | 55 | self.imageView.layer.cornerRadius = 3 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /MusicAppTransition/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | MusicAppTransition 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /MusicAppTransition/MusicCell.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 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /MusicAppTransition/PlayerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PlayerViewController.swift 3 | // MusicAppTransition 4 | // 5 | // Created by xxxAIRINxxx on 2018/08/03. 6 | // Copyright © 2018 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Movin 11 | 12 | final class PlayerViewController: UIViewController { 13 | 14 | @IBOutlet private(set) weak var nameLabel: UILabel! 15 | @IBOutlet private(set) weak var imageView: UIImageView! 16 | @IBOutlet private(set) weak var imageLayerView: UIView! 17 | @IBOutlet private(set) weak var backgroundView: UIView! 18 | @IBOutlet private(set) weak var blurView: UIVisualEffectView! 19 | @IBOutlet private(set) weak var closeButton: UIButton! 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | 24 | self.imageView.layer.cornerRadius = 5 25 | 26 | self.imageLayerView.clipsToBounds = false 27 | self.imageLayerView.layer.masksToBounds = false 28 | 29 | self.imageLayerView.layer.shadowOpacity = 0.8 30 | self.imageLayerView.layer.shadowColor = UIColor.gray.cgColor 31 | self.imageLayerView.layer.shadowOffset = CGSize(width: 0, height: 0) 32 | self.imageLayerView.layer.shadowRadius = 5 33 | self.imageLayerView.layer.cornerRadius = 5 34 | } 35 | 36 | override func viewWillAppear(_ animated: Bool) { 37 | super.viewWillAppear(animated) 38 | print("PlayerViewController - viewWillAppear") 39 | } 40 | 41 | override func viewDidAppear(_ animated: Bool) { 42 | super.viewDidAppear(animated) 43 | print("PlayerViewController - viewDidAppear") 44 | } 45 | 46 | override func viewWillDisappear(_ animated: Bool) { 47 | super.viewWillDisappear(animated) 48 | print("PlayerViewController - viewWillDisappear") 49 | } 50 | 51 | override func viewDidDisappear(_ animated: Bool) { 52 | super.viewDidDisappear(animated) 53 | print("PlayerViewController - viewDidDisappear") 54 | } 55 | 56 | @IBAction private func tapCloseButton() { 57 | self.dismiss(animated: true, completion: nil) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MusicAppTransition/TopViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TopViewController.swift 3 | // MusicAppTransition 4 | // 5 | // Created by xxxAIRINxxx on 2018/08/03. 6 | // Copyright © 2018 xxxAIRINxxx. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Movin 11 | 12 | final class TopViewController: UIViewController { 13 | 14 | @IBOutlet private weak var imageView: UIImageView! 15 | @IBOutlet private weak var imageLayerView: UIView! 16 | @IBOutlet private weak var containerView: UIView! 17 | @IBOutlet private weak var miniPlayerView: UIView! 18 | @IBOutlet private weak var miniPlayerButton : UIButton! 19 | 20 | internal var modalVC: UIViewController? 21 | private var movin: Movin? 22 | private var isPresented: Bool = false 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | self.imageView.layer.cornerRadius = 5 28 | 29 | self.imageLayerView.clipsToBounds = false 30 | self.imageLayerView.layer.masksToBounds = false 31 | 32 | self.imageLayerView.layer.shadowOpacity = 0.8 33 | self.imageLayerView.layer.shadowColor = UIColor.gray.cgColor 34 | self.imageLayerView.layer.shadowOffset = CGSize(width: 0, height: 0) 35 | self.imageLayerView.layer.shadowRadius = 2 36 | self.imageLayerView.layer.cornerRadius = 5 37 | 38 | let color = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 0.8) 39 | self.miniPlayerButton.setBackgroundImage(self.generateImageWithColor(color), for: .highlighted) 40 | } 41 | 42 | override var preferredStatusBarStyle: UIStatusBarStyle { 43 | if self.isPresented { 44 | return .lightContent 45 | } 46 | return .default 47 | } 48 | 49 | override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { 50 | return .fade 51 | } 52 | 53 | override func viewWillAppear(_ animated: Bool) { 54 | super.viewWillAppear(animated) 55 | print("TopViewController - viewWillAppear") 56 | } 57 | 58 | override func viewDidAppear(_ animated: Bool) { 59 | super.viewDidAppear(animated) 60 | print("TopViewController - viewDidAppear") 61 | self.setup() 62 | } 63 | 64 | override func viewWillDisappear(_ animated: Bool) { 65 | super.viewWillDisappear(animated) 66 | print("TopViewController - viewWillDisappear") 67 | } 68 | 69 | override func viewDidDisappear(_ animated: Bool) { 70 | super.viewDidDisappear(animated) 71 | print("TopViewController - viewDidDisappear") 72 | } 73 | 74 | private func setup() { 75 | if self.movin != nil { return } 76 | 77 | if #available(iOS 11.0, *) { 78 | self.movin = Movin(1.0, TimingCurve(curve: .easeInOut, dampingRatio: 0.8)) 79 | } else { 80 | self.movin = Movin(1.0) 81 | } 82 | 83 | let modal = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PlayerViewController") as! PlayerViewController 84 | modal.view.layoutIfNeeded() 85 | 86 | let miniPlayerOrigin = self.miniPlayerView.frame.origin 87 | let miniImageFrame = self.imageLayerView.frame 88 | let originImageFrame = modal.imageView.frame 89 | let endModalOrigin = CGPoint(x: 0, y: 55) 90 | 91 | self.movin!.addAnimations([ 92 | self.containerView.mvn.cornerRadius.from(0.0).to(10.0), 93 | self.containerView.mvn.alpha.from(1.0).to(0.6), 94 | self.containerView.mvn.transform.from(CGAffineTransform(scaleX: 1.0, y: 1.0)).to(CGAffineTransform(scaleX: 0.9, y: 0.9)), 95 | self.tabBarController!.tabBar.mvn.point.to(CGPoint(x: 0.0, y: self.view.frame.size.height)), 96 | modal.view.mvn.cornerRadius.from(0.0).to(10.0), 97 | modal.imageView.mvn.frame.from(miniImageFrame).to(originImageFrame), 98 | modal.imageLayerView.mvn.frame.from(miniImageFrame).to(originImageFrame), 99 | modal.view.mvn.point.from(miniPlayerOrigin).to(endModalOrigin), 100 | modal.backgroundView.mvn.alpha.from(0.0).to(1.0), 101 | modal.nameLabel.mvn.alpha.from(1.0).to(0.0), 102 | modal.closeButton.mvn.alpha.from(0.0).to(1.0), 103 | ]) 104 | 105 | let presentGesture = GestureAnimating(self.miniPlayerView, .top, self.view.frame.size) 106 | presentGesture.panCompletionThresholdRatio = 0.4 107 | let dismissGesture = GestureAnimating(modal.view, .bottom, modal.view.frame.size) 108 | dismissGesture.panCompletionThresholdRatio = 0.25 109 | dismissGesture.smoothness = 0.5 110 | 111 | let transition = Transition(self.movin!, self.tabBarController!, modal, GestureTransitioning(.present, presentGesture, dismissGesture)) 112 | transition.customContainerViewSetupHandler = { [unowned self] type, containerView in 113 | if type.isPresenting { 114 | self.miniPlayerView.isHidden = true 115 | containerView.addSubview(modal.view) 116 | containerView.addSubview(self.tabBarController!.tabBar) 117 | modal.view.layoutIfNeeded() 118 | 119 | self.isPresented = true 120 | self.setNeedsStatusBarAppearanceUpdate() 121 | 122 | self.tabBarController?.beginAppearanceTransition(false, animated: false) 123 | modal.beginAppearanceTransition(true, animated: false) 124 | } else { 125 | self.tabBarController?.beginAppearanceTransition(true, animated: false) 126 | modal.beginAppearanceTransition(false, animated: false) 127 | } 128 | } 129 | transition.customContainerViewCompletionHandler = { [unowned self] type, didComplete, containerView in 130 | self.tabBarController?.endAppearanceTransition() 131 | modal.endAppearanceTransition() 132 | 133 | if type.isDismissing { 134 | if didComplete { 135 | print("complete dismiss") 136 | modal.view.removeFromSuperview() 137 | self.tabBarController?.tabBar.removeFromSuperview() 138 | self.tabBarController?.view.addSubview(self.tabBarController!.tabBar) 139 | 140 | self.miniPlayerView.isHidden = false 141 | self.movin = nil 142 | self.modalVC = nil 143 | self.isPresented = false 144 | self.setNeedsStatusBarAppearanceUpdate() 145 | 146 | self.setup() 147 | } else { 148 | print("cancel dismiss") 149 | } 150 | } else { 151 | if didComplete { 152 | print("complete present") 153 | } else { 154 | print("cancel present") 155 | modal.view.removeFromSuperview() 156 | self.tabBarController?.tabBar.removeFromSuperview() 157 | self.tabBarController?.view.addSubview(self.tabBarController!.tabBar) 158 | 159 | self.miniPlayerView.isHidden = false 160 | self.isPresented = false 161 | self.setNeedsStatusBarAppearanceUpdate() 162 | } 163 | } 164 | } 165 | 166 | self.modalVC = modal 167 | modal.modalPresentationStyle = .overCurrentContext 168 | modal.transitioningDelegate = self.movin!.configureCustomTransition(transition) 169 | } 170 | 171 | fileprivate func generateImageWithColor(_ color: UIColor) -> UIImage { 172 | let rect = CGRect(x: 0, y: 0, width: 1, height: 1) 173 | 174 | UIGraphicsBeginImageContext(rect.size) 175 | let context = UIGraphicsGetCurrentContext() 176 | 177 | context?.setFillColor(color.cgColor) 178 | context?.fill(rect) 179 | 180 | let image = UIGraphicsGetImageFromCurrentImageContext() 181 | UIGraphicsEndImageContext() 182 | 183 | return image! 184 | } 185 | 186 | @IBAction private func tapMiniPlayerButton() { 187 | guard let m = self.modalVC else { return } 188 | self.present(m, animated: true, completion: nil) 189 | } 190 | } 191 | 192 | final class LineView: UIView { 193 | 194 | override func draw(_ rect: CGRect) { 195 | super.draw(rect) 196 | 197 | let topLine = UIBezierPath(rect: CGRect(x: 0, y: 0, width: self.frame.size.width, height: 0.2)) 198 | UIColor.gray.setStroke() 199 | topLine.lineWidth = 0.2 200 | topLine.stroke() 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /MusicAppTransition/tia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxAIRINxxx/MusicAppTransition/0e67dda3633339e8a269cf3749640f960844143f/MusicAppTransition/tia.jpg -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | 2 | project 'MusicAppTransition.xcodeproj' 3 | 4 | platform :ios, '10.0' 5 | use_frameworks! 6 | 7 | target 'MusicAppTransition' do 8 | 9 | pod 'Movin' 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Movin (1.2.0) 3 | 4 | DEPENDENCIES: 5 | - Movin 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - Movin 10 | 11 | SPEC CHECKSUMS: 12 | Movin: 02a488d93913e46de77774d6a2cc2fa0eec83760 13 | 14 | PODFILE CHECKSUM: 01ab440746fffcd160802a18e9a7495e616d01e8 15 | 16 | COCOAPODS: 1.6.1 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MusicAppTransition 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 interactive transition like Apple's Music App (over iOS 10). written in Swift. 10 | 11 | ## Demo 12 | 13 | [See demo on Appetize.io](https://appetize.io/app/gf2qvbj17m2fcngwg88k37m6gc?device=iphone6s&scale=75&orientation=portrait&osVersion=11.4) 14 | 15 | 16 | ## Using Transition Animator 17 | 18 | This sample have created as a showcase of Movin. 19 | 20 | [Movin](https://github.com/xxxAIRINxxx/Movin) 21 | 22 | 23 | ## Requirements 24 | 25 | * iOS 10.0+ 26 | * Swift 5.0+ 27 | * Xcode 10.2+ 28 | * CocoaPods 1.6.1+ 29 | 30 | ## License 31 | 32 | MIT license. See the LICENSE file for more info. 33 | -------------------------------------------------------------------------------- /capture.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxAIRINxxx/MusicAppTransition/0e67dda3633339e8a269cf3749640f960844143f/capture.gif --------------------------------------------------------------------------------