├── .gitignore ├── README.md ├── iPod.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── iPod.xcscheme ├── iPod ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── shell.colorset │ │ └── Contents.json │ └── wheel.colorset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── ContentView.swift ├── DisplayView.swift ├── Info.plist ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── SceneDelegate.swift └── WheelView.swift └── images └── xcode.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | *Tests/ 6 | .DS_Store 7 | 8 | ## User settings 9 | xcuserdata/ 10 | 11 | 12 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 13 | *.xcscmblueprint 14 | *.xccheckout 15 | 16 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 17 | build/ 18 | DerivedData/ 19 | *.moved-aside 20 | *.pbxuser 21 | !default.pbxuser 22 | *.mode1v3 23 | !default.mode1v3 24 | *.mode2v3 25 | !default.mode2v3 26 | *.perspectivev3 27 | !default.perspectivev3 28 | 29 | ## Obj-C/Swift specific 30 | *.hmap 31 | 32 | ## App packaging 33 | *.ipa 34 | *.dSYM.zip 35 | *.dSYM 36 | 37 | ## Playgrounds 38 | timeline.xctimeline 39 | playground.xcworkspace 40 | 41 | # Swift Package Manager 42 | # 43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 44 | # Packages/ 45 | # Package.pins 46 | # Package.resolved 47 | # *.xcodeproj 48 | # 49 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 50 | # hence it is not needed unless you have added a package configuration file to your project 51 | # .swiftpm 52 | 53 | .build/ 54 | 55 | # CocoaPods 56 | # 57 | # We recommend against adding the Pods directory to your .gitignore. However 58 | # you should judge for yourself, the pros and cons are mentioned at: 59 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 60 | # 61 | # Pods/ 62 | # 63 | # Add this line if you want to avoid checking in source code from the Xcode workspace 64 | # *.xcworkspace 65 | 66 | # Carthage 67 | # 68 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 69 | # Carthage/Checkouts 70 | 71 | Carthage/Build/ 72 | 73 | # Accio dependency management 74 | Dependencies/ 75 | .accio/ 76 | 77 | # fastlane 78 | # 79 | # It is recommended to not store the screenshots in the git repo. 80 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 81 | # For more information about the recommended setup visit: 82 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 83 | 84 | fastlane/report.xml 85 | fastlane/Preview.html 86 | fastlane/screenshots/**/*.png 87 | fastlane/test_output 88 | 89 | # Code Injection 90 | # 91 | # After new code Injection tools there's a generated folder /iOSInjectionProject 92 | # https://github.com/johnno1962/injectionforxcode 93 | 94 | iOSInjectionProject/ 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iPodClassicUI 2 | User Interface of iPod classic built by SwiftUI 3 | 4 | Here for a detailed description of this project. 5 | 6 | [iPod classicのUIを再現する](https://d1v1b.com/swiftui/ipod_classic_ui) 7 | 8 | ![image](/images/xcode.png) 9 | -------------------------------------------------------------------------------- /iPod.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D44838692435F03200EC3DFE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44838682435F03200EC3DFE /* AppDelegate.swift */; }; 11 | D448386B2435F03200EC3DFE /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D448386A2435F03200EC3DFE /* SceneDelegate.swift */; }; 12 | D448386D2435F03200EC3DFE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D448386C2435F03200EC3DFE /* ContentView.swift */; }; 13 | D448386F2435F03600EC3DFE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D448386E2435F03600EC3DFE /* Assets.xcassets */; }; 14 | D44838722435F03600EC3DFE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D44838712435F03600EC3DFE /* Preview Assets.xcassets */; }; 15 | D44838752435F03600EC3DFE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D44838732435F03600EC3DFE /* LaunchScreen.storyboard */; }; 16 | D448389B243614A600EC3DFE /* WheelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D448389A243614A600EC3DFE /* WheelView.swift */; }; 17 | D448389D2436180700EC3DFE /* DisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D448389C2436180700EC3DFE /* DisplayView.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | D448387C2435F03700EC3DFE /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = D448385D2435F03200EC3DFE /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = D44838642435F03200EC3DFE; 26 | remoteInfo = iPod; 27 | }; 28 | D44838872435F03700EC3DFE /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = D448385D2435F03200EC3DFE /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = D44838642435F03200EC3DFE; 33 | remoteInfo = iPod; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | D44838652435F03200EC3DFE /* iPod.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPod.app; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | D44838682435F03200EC3DFE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | D448386A2435F03200EC3DFE /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 41 | D448386C2435F03200EC3DFE /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 42 | D448386E2435F03600EC3DFE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | D44838712435F03600EC3DFE /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 44 | D44838742435F03600EC3DFE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | D44838762435F03600EC3DFE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | D448387B2435F03700EC3DFE /* iPodTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iPodTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | D44838862435F03700EC3DFE /* iPodUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iPodUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | D448389A243614A600EC3DFE /* WheelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WheelView.swift; sourceTree = ""; }; 49 | D448389C2436180700EC3DFE /* DisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayView.swift; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | D44838622435F03200EC3DFE /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | D44838782435F03700EC3DFE /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | D44838832435F03700EC3DFE /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | /* End PBXFrameworksBuildPhase section */ 75 | 76 | /* Begin PBXGroup section */ 77 | D448385C2435F03200EC3DFE = { 78 | isa = PBXGroup; 79 | children = ( 80 | D44838672435F03200EC3DFE /* iPod */, 81 | D44838662435F03200EC3DFE /* Products */, 82 | ); 83 | sourceTree = ""; 84 | }; 85 | D44838662435F03200EC3DFE /* Products */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | D44838652435F03200EC3DFE /* iPod.app */, 89 | D448387B2435F03700EC3DFE /* iPodTests.xctest */, 90 | D44838862435F03700EC3DFE /* iPodUITests.xctest */, 91 | ); 92 | name = Products; 93 | sourceTree = ""; 94 | }; 95 | D44838672435F03200EC3DFE /* iPod */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | D44838682435F03200EC3DFE /* AppDelegate.swift */, 99 | D448386A2435F03200EC3DFE /* SceneDelegate.swift */, 100 | D448386C2435F03200EC3DFE /* ContentView.swift */, 101 | D448386E2435F03600EC3DFE /* Assets.xcassets */, 102 | D44838732435F03600EC3DFE /* LaunchScreen.storyboard */, 103 | D44838762435F03600EC3DFE /* Info.plist */, 104 | D44838702435F03600EC3DFE /* Preview Content */, 105 | D448389C2436180700EC3DFE /* DisplayView.swift */, 106 | D448389A243614A600EC3DFE /* WheelView.swift */, 107 | ); 108 | path = iPod; 109 | sourceTree = ""; 110 | }; 111 | D44838702435F03600EC3DFE /* Preview Content */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | D44838712435F03600EC3DFE /* Preview Assets.xcassets */, 115 | ); 116 | path = "Preview Content"; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | D44838642435F03200EC3DFE /* iPod */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = D448388F2435F03700EC3DFE /* Build configuration list for PBXNativeTarget "iPod" */; 125 | buildPhases = ( 126 | D44838612435F03200EC3DFE /* Sources */, 127 | D44838622435F03200EC3DFE /* Frameworks */, 128 | D44838632435F03200EC3DFE /* Resources */, 129 | ); 130 | buildRules = ( 131 | ); 132 | dependencies = ( 133 | ); 134 | name = iPod; 135 | productName = iPod; 136 | productReference = D44838652435F03200EC3DFE /* iPod.app */; 137 | productType = "com.apple.product-type.application"; 138 | }; 139 | D448387A2435F03700EC3DFE /* iPodTests */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = D44838922435F03700EC3DFE /* Build configuration list for PBXNativeTarget "iPodTests" */; 142 | buildPhases = ( 143 | D44838772435F03700EC3DFE /* Sources */, 144 | D44838782435F03700EC3DFE /* Frameworks */, 145 | D44838792435F03700EC3DFE /* Resources */, 146 | ); 147 | buildRules = ( 148 | ); 149 | dependencies = ( 150 | D448387D2435F03700EC3DFE /* PBXTargetDependency */, 151 | ); 152 | name = iPodTests; 153 | productName = iPodTests; 154 | productReference = D448387B2435F03700EC3DFE /* iPodTests.xctest */; 155 | productType = "com.apple.product-type.bundle.unit-test"; 156 | }; 157 | D44838852435F03700EC3DFE /* iPodUITests */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = D44838952435F03700EC3DFE /* Build configuration list for PBXNativeTarget "iPodUITests" */; 160 | buildPhases = ( 161 | D44838822435F03700EC3DFE /* Sources */, 162 | D44838832435F03700EC3DFE /* Frameworks */, 163 | D44838842435F03700EC3DFE /* Resources */, 164 | ); 165 | buildRules = ( 166 | ); 167 | dependencies = ( 168 | D44838882435F03700EC3DFE /* PBXTargetDependency */, 169 | ); 170 | name = iPodUITests; 171 | productName = iPodUITests; 172 | productReference = D44838862435F03700EC3DFE /* iPodUITests.xctest */; 173 | productType = "com.apple.product-type.bundle.ui-testing"; 174 | }; 175 | /* End PBXNativeTarget section */ 176 | 177 | /* Begin PBXProject section */ 178 | D448385D2435F03200EC3DFE /* Project object */ = { 179 | isa = PBXProject; 180 | attributes = { 181 | LastSwiftUpdateCheck = 1140; 182 | LastUpgradeCheck = 1140; 183 | ORGANIZATIONNAME = d1v1b; 184 | TargetAttributes = { 185 | D44838642435F03200EC3DFE = { 186 | CreatedOnToolsVersion = 11.4; 187 | }; 188 | D448387A2435F03700EC3DFE = { 189 | CreatedOnToolsVersion = 11.4; 190 | TestTargetID = D44838642435F03200EC3DFE; 191 | }; 192 | D44838852435F03700EC3DFE = { 193 | CreatedOnToolsVersion = 11.4; 194 | TestTargetID = D44838642435F03200EC3DFE; 195 | }; 196 | }; 197 | }; 198 | buildConfigurationList = D44838602435F03200EC3DFE /* Build configuration list for PBXProject "iPod" */; 199 | compatibilityVersion = "Xcode 9.3"; 200 | developmentRegion = en; 201 | hasScannedForEncodings = 0; 202 | knownRegions = ( 203 | en, 204 | Base, 205 | ); 206 | mainGroup = D448385C2435F03200EC3DFE; 207 | productRefGroup = D44838662435F03200EC3DFE /* Products */; 208 | projectDirPath = ""; 209 | projectRoot = ""; 210 | targets = ( 211 | D44838642435F03200EC3DFE /* iPod */, 212 | D448387A2435F03700EC3DFE /* iPodTests */, 213 | D44838852435F03700EC3DFE /* iPodUITests */, 214 | ); 215 | }; 216 | /* End PBXProject section */ 217 | 218 | /* Begin PBXResourcesBuildPhase section */ 219 | D44838632435F03200EC3DFE /* Resources */ = { 220 | isa = PBXResourcesBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | D44838752435F03600EC3DFE /* LaunchScreen.storyboard in Resources */, 224 | D44838722435F03600EC3DFE /* Preview Assets.xcassets in Resources */, 225 | D448386F2435F03600EC3DFE /* Assets.xcassets in Resources */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | D44838792435F03700EC3DFE /* Resources */ = { 230 | isa = PBXResourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | ); 234 | runOnlyForDeploymentPostprocessing = 0; 235 | }; 236 | D44838842435F03700EC3DFE /* Resources */ = { 237 | isa = PBXResourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | /* End PBXResourcesBuildPhase section */ 244 | 245 | /* Begin PBXSourcesBuildPhase section */ 246 | D44838612435F03200EC3DFE /* Sources */ = { 247 | isa = PBXSourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | D44838692435F03200EC3DFE /* AppDelegate.swift in Sources */, 251 | D448386B2435F03200EC3DFE /* SceneDelegate.swift in Sources */, 252 | D448389B243614A600EC3DFE /* WheelView.swift in Sources */, 253 | D448389D2436180700EC3DFE /* DisplayView.swift in Sources */, 254 | D448386D2435F03200EC3DFE /* ContentView.swift in Sources */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | D44838772435F03700EC3DFE /* Sources */ = { 259 | isa = PBXSourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | D44838822435F03700EC3DFE /* Sources */ = { 266 | isa = PBXSourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXSourcesBuildPhase section */ 273 | 274 | /* Begin PBXTargetDependency section */ 275 | D448387D2435F03700EC3DFE /* PBXTargetDependency */ = { 276 | isa = PBXTargetDependency; 277 | target = D44838642435F03200EC3DFE /* iPod */; 278 | targetProxy = D448387C2435F03700EC3DFE /* PBXContainerItemProxy */; 279 | }; 280 | D44838882435F03700EC3DFE /* PBXTargetDependency */ = { 281 | isa = PBXTargetDependency; 282 | target = D44838642435F03200EC3DFE /* iPod */; 283 | targetProxy = D44838872435F03700EC3DFE /* PBXContainerItemProxy */; 284 | }; 285 | /* End PBXTargetDependency section */ 286 | 287 | /* Begin PBXVariantGroup section */ 288 | D44838732435F03600EC3DFE /* LaunchScreen.storyboard */ = { 289 | isa = PBXVariantGroup; 290 | children = ( 291 | D44838742435F03600EC3DFE /* Base */, 292 | ); 293 | name = LaunchScreen.storyboard; 294 | sourceTree = ""; 295 | }; 296 | /* End PBXVariantGroup section */ 297 | 298 | /* Begin XCBuildConfiguration section */ 299 | D448388D2435F03700EC3DFE /* Debug */ = { 300 | isa = XCBuildConfiguration; 301 | buildSettings = { 302 | ALWAYS_SEARCH_USER_PATHS = NO; 303 | CLANG_ANALYZER_NONNULL = YES; 304 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 306 | CLANG_CXX_LIBRARY = "libc++"; 307 | CLANG_ENABLE_MODULES = YES; 308 | CLANG_ENABLE_OBJC_ARC = YES; 309 | CLANG_ENABLE_OBJC_WEAK = YES; 310 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 311 | CLANG_WARN_BOOL_CONVERSION = YES; 312 | CLANG_WARN_COMMA = YES; 313 | CLANG_WARN_CONSTANT_CONVERSION = YES; 314 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 316 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 329 | CLANG_WARN_UNREACHABLE_CODE = YES; 330 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu11; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 350 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 351 | MTL_FAST_MATH = YES; 352 | ONLY_ACTIVE_ARCH = YES; 353 | SDKROOT = iphoneos; 354 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 355 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 356 | }; 357 | name = Debug; 358 | }; 359 | D448388E2435F03700EC3DFE /* Release */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CLANG_ANALYZER_NONNULL = YES; 364 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_MODULES = YES; 368 | CLANG_ENABLE_OBJC_ARC = YES; 369 | CLANG_ENABLE_OBJC_WEAK = YES; 370 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 371 | CLANG_WARN_BOOL_CONVERSION = YES; 372 | CLANG_WARN_COMMA = YES; 373 | CLANG_WARN_CONSTANT_CONVERSION = YES; 374 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 375 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 376 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 377 | CLANG_WARN_EMPTY_BODY = YES; 378 | CLANG_WARN_ENUM_CONVERSION = YES; 379 | CLANG_WARN_INFINITE_RECURSION = YES; 380 | CLANG_WARN_INT_CONVERSION = YES; 381 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 382 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 383 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 384 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 385 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 386 | CLANG_WARN_STRICT_PROTOTYPES = YES; 387 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 388 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 389 | CLANG_WARN_UNREACHABLE_CODE = YES; 390 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 391 | COPY_PHASE_STRIP = NO; 392 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 393 | ENABLE_NS_ASSERTIONS = NO; 394 | ENABLE_STRICT_OBJC_MSGSEND = YES; 395 | GCC_C_LANGUAGE_STANDARD = gnu11; 396 | GCC_NO_COMMON_BLOCKS = YES; 397 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 398 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 399 | GCC_WARN_UNDECLARED_SELECTOR = YES; 400 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 401 | GCC_WARN_UNUSED_FUNCTION = YES; 402 | GCC_WARN_UNUSED_VARIABLE = YES; 403 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 404 | MTL_ENABLE_DEBUG_INFO = NO; 405 | MTL_FAST_MATH = YES; 406 | SDKROOT = iphoneos; 407 | SWIFT_COMPILATION_MODE = wholemodule; 408 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 409 | VALIDATE_PRODUCT = YES; 410 | }; 411 | name = Release; 412 | }; 413 | D44838902435F03700EC3DFE /* Debug */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 417 | CODE_SIGN_STYLE = Automatic; 418 | DEVELOPMENT_ASSET_PATHS = "\"iPod/Preview Content\""; 419 | DEVELOPMENT_TEAM = 4CGNPZHPL4; 420 | ENABLE_PREVIEWS = YES; 421 | INFOPLIST_FILE = iPod/Info.plist; 422 | LD_RUNPATH_SEARCH_PATHS = ( 423 | "$(inherited)", 424 | "@executable_path/Frameworks", 425 | ); 426 | PRODUCT_BUNDLE_IDENTIFIER = d1v1b.iPod; 427 | PRODUCT_NAME = "$(TARGET_NAME)"; 428 | SWIFT_VERSION = 5.0; 429 | TARGETED_DEVICE_FAMILY = "1,2"; 430 | }; 431 | name = Debug; 432 | }; 433 | D44838912435F03700EC3DFE /* Release */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 437 | CODE_SIGN_STYLE = Automatic; 438 | DEVELOPMENT_ASSET_PATHS = "\"iPod/Preview Content\""; 439 | DEVELOPMENT_TEAM = 4CGNPZHPL4; 440 | ENABLE_PREVIEWS = YES; 441 | INFOPLIST_FILE = iPod/Info.plist; 442 | LD_RUNPATH_SEARCH_PATHS = ( 443 | "$(inherited)", 444 | "@executable_path/Frameworks", 445 | ); 446 | PRODUCT_BUNDLE_IDENTIFIER = d1v1b.iPod; 447 | PRODUCT_NAME = "$(TARGET_NAME)"; 448 | SWIFT_VERSION = 5.0; 449 | TARGETED_DEVICE_FAMILY = "1,2"; 450 | }; 451 | name = Release; 452 | }; 453 | D44838932435F03700EC3DFE /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 457 | BUNDLE_LOADER = "$(TEST_HOST)"; 458 | CODE_SIGN_STYLE = Automatic; 459 | INFOPLIST_FILE = iPodTests/Info.plist; 460 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 461 | LD_RUNPATH_SEARCH_PATHS = ( 462 | "$(inherited)", 463 | "@executable_path/Frameworks", 464 | "@loader_path/Frameworks", 465 | ); 466 | PRODUCT_BUNDLE_IDENTIFIER = d1v1b.iPodTests; 467 | PRODUCT_NAME = "$(TARGET_NAME)"; 468 | SWIFT_VERSION = 5.0; 469 | TARGETED_DEVICE_FAMILY = "1,2"; 470 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iPod.app/iPod"; 471 | }; 472 | name = Debug; 473 | }; 474 | D44838942435F03700EC3DFE /* Release */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 478 | BUNDLE_LOADER = "$(TEST_HOST)"; 479 | CODE_SIGN_STYLE = Automatic; 480 | INFOPLIST_FILE = iPodTests/Info.plist; 481 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 482 | LD_RUNPATH_SEARCH_PATHS = ( 483 | "$(inherited)", 484 | "@executable_path/Frameworks", 485 | "@loader_path/Frameworks", 486 | ); 487 | PRODUCT_BUNDLE_IDENTIFIER = d1v1b.iPodTests; 488 | PRODUCT_NAME = "$(TARGET_NAME)"; 489 | SWIFT_VERSION = 5.0; 490 | TARGETED_DEVICE_FAMILY = "1,2"; 491 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iPod.app/iPod"; 492 | }; 493 | name = Release; 494 | }; 495 | D44838962435F03700EC3DFE /* Debug */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 499 | CODE_SIGN_STYLE = Automatic; 500 | INFOPLIST_FILE = iPodUITests/Info.plist; 501 | LD_RUNPATH_SEARCH_PATHS = ( 502 | "$(inherited)", 503 | "@executable_path/Frameworks", 504 | "@loader_path/Frameworks", 505 | ); 506 | PRODUCT_BUNDLE_IDENTIFIER = d1v1b.iPodUITests; 507 | PRODUCT_NAME = "$(TARGET_NAME)"; 508 | SWIFT_VERSION = 5.0; 509 | TARGETED_DEVICE_FAMILY = "1,2"; 510 | TEST_TARGET_NAME = iPod; 511 | }; 512 | name = Debug; 513 | }; 514 | D44838972435F03700EC3DFE /* Release */ = { 515 | isa = XCBuildConfiguration; 516 | buildSettings = { 517 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 518 | CODE_SIGN_STYLE = Automatic; 519 | INFOPLIST_FILE = iPodUITests/Info.plist; 520 | LD_RUNPATH_SEARCH_PATHS = ( 521 | "$(inherited)", 522 | "@executable_path/Frameworks", 523 | "@loader_path/Frameworks", 524 | ); 525 | PRODUCT_BUNDLE_IDENTIFIER = d1v1b.iPodUITests; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | SWIFT_VERSION = 5.0; 528 | TARGETED_DEVICE_FAMILY = "1,2"; 529 | TEST_TARGET_NAME = iPod; 530 | }; 531 | name = Release; 532 | }; 533 | /* End XCBuildConfiguration section */ 534 | 535 | /* Begin XCConfigurationList section */ 536 | D44838602435F03200EC3DFE /* Build configuration list for PBXProject "iPod" */ = { 537 | isa = XCConfigurationList; 538 | buildConfigurations = ( 539 | D448388D2435F03700EC3DFE /* Debug */, 540 | D448388E2435F03700EC3DFE /* Release */, 541 | ); 542 | defaultConfigurationIsVisible = 0; 543 | defaultConfigurationName = Release; 544 | }; 545 | D448388F2435F03700EC3DFE /* Build configuration list for PBXNativeTarget "iPod" */ = { 546 | isa = XCConfigurationList; 547 | buildConfigurations = ( 548 | D44838902435F03700EC3DFE /* Debug */, 549 | D44838912435F03700EC3DFE /* Release */, 550 | ); 551 | defaultConfigurationIsVisible = 0; 552 | defaultConfigurationName = Release; 553 | }; 554 | D44838922435F03700EC3DFE /* Build configuration list for PBXNativeTarget "iPodTests" */ = { 555 | isa = XCConfigurationList; 556 | buildConfigurations = ( 557 | D44838932435F03700EC3DFE /* Debug */, 558 | D44838942435F03700EC3DFE /* Release */, 559 | ); 560 | defaultConfigurationIsVisible = 0; 561 | defaultConfigurationName = Release; 562 | }; 563 | D44838952435F03700EC3DFE /* Build configuration list for PBXNativeTarget "iPodUITests" */ = { 564 | isa = XCConfigurationList; 565 | buildConfigurations = ( 566 | D44838962435F03700EC3DFE /* Debug */, 567 | D44838972435F03700EC3DFE /* Release */, 568 | ); 569 | defaultConfigurationIsVisible = 0; 570 | defaultConfigurationName = Release; 571 | }; 572 | /* End XCConfigurationList section */ 573 | }; 574 | rootObject = D448385D2435F03200EC3DFE /* Project object */; 575 | } 576 | -------------------------------------------------------------------------------- /iPod.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iPod.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iPod.xcodeproj/xcshareddata/xcschemes/iPod.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /iPod/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // iPod 4 | // 5 | // Copyright © 2020 d1v1b. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | @UIApplicationMain 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /iPod/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /iPod/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iPod/Assets.xcassets/shell.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "1.000", 9 | "green" : "1.000", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "light" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "1.000", 27 | "green" : "1.000", 28 | "red" : "1.000" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | }, 33 | { 34 | "appearances" : [ 35 | { 36 | "appearance" : "luminosity", 37 | "value" : "dark" 38 | } 39 | ], 40 | "color" : { 41 | "color-space" : "srgb", 42 | "components" : { 43 | "alpha" : "1.000", 44 | "blue" : "0.000", 45 | "green" : "0.000", 46 | "red" : "0.000" 47 | } 48 | }, 49 | "idiom" : "universal" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /iPod/Assets.xcassets/wheel.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.653", 9 | "green" : "0.634", 10 | "red" : "0.636" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "light" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.653", 27 | "green" : "0.634", 28 | "red" : "0.636" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | }, 33 | { 34 | "appearances" : [ 35 | { 36 | "appearance" : "luminosity", 37 | "value" : "dark" 38 | } 39 | ], 40 | "color" : { 41 | "color-space" : "srgb", 42 | "components" : { 43 | "alpha" : "1.000", 44 | "blue" : "0.370", 45 | "green" : "0.360", 46 | "red" : "0.360" 47 | } 48 | }, 49 | "idiom" : "universal" 50 | } 51 | ], 52 | "info" : { 53 | "author" : "xcode", 54 | "version" : 1 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /iPod/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 | -------------------------------------------------------------------------------- /iPod/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Copyright © 2020 d1v1b.com All rights reserved. 4 | // 5 | 6 | import SwiftUI 7 | 8 | struct Menu: Identifiable { 9 | let id: Int 10 | let name: String 11 | let next: Bool 12 | } 13 | 14 | struct ContentView: View { 15 | @State private var menus: [Menu] = [ 16 | Menu(id: 0, name: "Music", next: true), 17 | Menu(id: 1, name: "Photos", next: true), 18 | Menu(id: 2, name: "Videos", next: true), 19 | Menu(id: 3, name: "Extras", next: true), 20 | Menu(id: 4, name: "Settings", next: true), 21 | Menu(id: 5, name: "Shuffle Songs", next: false) 22 | ] 23 | @State private var menuIndex : Int = 0 24 | 25 | var body: some View { 26 | VStack () { 27 | Spacer() 28 | DisplayView(menus: self.$menus, menuIndex: self.$menuIndex) 29 | Spacer() 30 | WheelView(menus: self.$menus, menuIndex: self.$menuIndex) 31 | Spacer() 32 | } 33 | } 34 | } 35 | 36 | struct ContentView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | ContentView() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /iPod/DisplayView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DisplayView.swift 3 | // 4 | 5 | import SwiftUI 6 | 7 | struct DisplayView: View { 8 | @Binding var menus: [Menu] 9 | @Binding var menuIndex: Int 10 | 11 | var body: some View { 12 | VStack (spacing: 0) { 13 | Text("iPod") 14 | .font(.system(size: 25)) 15 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 30, maxHeight: 30) 16 | .background(Color.gray) 17 | ForEach(self.menus) { menu in 18 | HStack () { 19 | Text(menu.name) 20 | .font(.system(size: 25)) 21 | Spacer() 22 | if (menu.next){ 23 | Image(systemName: "chevron.right") 24 | } 25 | } 26 | .padding(.horizontal, 5) 27 | .foregroundColor(menu.id == self.menuIndex ? .white : .black) 28 | .background(menu.id == self.menuIndex ? Color.blue : Color.white) 29 | } 30 | Spacer() 31 | } 32 | .background(Color.white) 33 | .frame(minWidth: 0, maxWidth: .infinity, minHeight: 300, maxHeight: 300) 34 | .clipShape(RoundedRectangle(cornerRadius: 5)) 35 | .overlay(RoundedRectangle(cornerRadius: 5).stroke(lineWidth: 2).foregroundColor(Color.gray)) 36 | .padding(.horizontal) 37 | } 38 | } 39 | 40 | struct DisplayView_Previews: PreviewProvider { 41 | @State static var menus: [Menu] = [ 42 | Menu(id: 0, name: "Music", next: true), 43 | Menu(id: 1, name: "Photos", next: true), 44 | ] 45 | 46 | @State static var menuIndex : Int = 0 47 | 48 | static var previews: some View { 49 | DisplayView(menus: $menus, menuIndex: $menuIndex) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /iPod/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | 37 | 38 | 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | 50 | UISupportedInterfaceOrientations~ipad 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationPortraitUpsideDown 54 | UIInterfaceOrientationLandscapeLeft 55 | UIInterfaceOrientationLandscapeRight 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /iPod/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iPod/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // iPod 4 | // 5 | // Copyright © 2020 d1v1b. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import SwiftUI 10 | 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | 21 | // Create the SwiftUI view that provides the window contents. 22 | let contentView = ContentView() 23 | 24 | // Use a UIHostingController as window root view controller. 25 | if let windowScene = scene as? UIWindowScene { 26 | let window = UIWindow(windowScene: windowScene) 27 | window.rootViewController = UIHostingController(rootView: contentView) 28 | self.window = window 29 | window.makeKeyAndVisible() 30 | } 31 | } 32 | 33 | func sceneDidDisconnect(_ scene: UIScene) { 34 | // Called as the scene is being released by the system. 35 | // This occurs shortly after the scene enters the background, or when its session is discarded. 36 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 37 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 38 | } 39 | 40 | func sceneDidBecomeActive(_ scene: UIScene) { 41 | // Called when the scene has moved from an inactive state to an active state. 42 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 43 | } 44 | 45 | func sceneWillResignActive(_ scene: UIScene) { 46 | // Called when the scene will move from an active state to an inactive state. 47 | // This may occur due to temporary interruptions (ex. an incoming phone call). 48 | } 49 | 50 | func sceneWillEnterForeground(_ scene: UIScene) { 51 | // Called as the scene transitions from the background to the foreground. 52 | // Use this method to undo the changes made on entering the background. 53 | } 54 | 55 | func sceneDidEnterBackground(_ scene: UIScene) { 56 | // Called as the scene transitions from the foreground to the background. 57 | // Use this method to save data, release shared resources, and store enough scene-specific state information 58 | // to restore the scene back to its current state. 59 | } 60 | 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /iPod/WheelView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WheelView.swift 3 | // Copyright © 2020 d1v1b.com All rights reserved. 4 | // 5 | 6 | import SwiftUI 7 | import AVFoundation 8 | 9 | struct WheelView: View { 10 | @Binding var menus: [Menu] 11 | @Binding var menuIndex: Int 12 | @State private var lastAngle: CGFloat = 0 13 | @State private var counter: CGFloat = 0 14 | 15 | var body: some View { 16 | GeometryReader { geometry in 17 | ZStack () { 18 | Circle() 19 | .frame(width: geometry.size.width, height: geometry.size.width) 20 | .foregroundColor(Color("wheel")) 21 | .gesture(DragGesture() 22 | .onChanged{ v in 23 | // 回転角を計算する 24 | var angle = atan2(v.location.x - geometry.size.width / 2, geometry.size.width / 2 - v.location.y) * 180 / .pi 25 | if (angle < 0) { angle += 360 } 26 | // 回転差分を計算する 27 | let theta = self.lastAngle - angle 28 | self.lastAngle = angle 29 | // 少ない回転角のものを積み上げていく 30 | if (abs(theta) < 20) { 31 | self.counter += theta 32 | } 33 | // counterが20以上(以下)になったらメニューを移動 34 | if (self.counter > 20 && self.menuIndex > 0) { 35 | self.menuIndex -= 1 36 | AudioServicesPlaySystemSound (1104) 37 | } else if (self.counter < -20 && self.menuIndex < self.menus.count - 1) { 38 | self.menuIndex += 1 39 | AudioServicesPlaySystemSound (1104) 40 | } 41 | if (abs(self.counter) > 20) { self.counter = 0 } 42 | } 43 | .onEnded { v in 44 | self.counter = 0 45 | } 46 | ) 47 | .overlay( 48 | Circle() 49 | .frame(width: geometry.size.width * 0.35, height: geometry.size.width * 0.35) 50 | .foregroundColor(Color("shell")) 51 | .gesture( 52 | TapGesture(count: 1) 53 | .onEnded { 54 | AudioServicesPlaySystemSound (1104) 55 | print("Tapped") 56 | } 57 | ) 58 | ) 59 | Text("MENU") 60 | .font(.title) 61 | .foregroundColor(.white) 62 | .offset(y: -150) 63 | Image(systemName: "playpause.fill") 64 | .font(.title) 65 | .foregroundColor(.white) 66 | .offset(y: 150) 67 | Image(systemName: "forward.end.alt.fill") 68 | .font(.title) 69 | .foregroundColor(.white) 70 | .offset(x: 150) 71 | Image(systemName: "backward.end.alt.fill") 72 | .font(.title) 73 | .foregroundColor(.white) 74 | .offset(x: -150) 75 | } 76 | }.padding(.horizontal) 77 | .padding(.top, 30) 78 | } 79 | } 80 | 81 | struct WheelView_Previews: PreviewProvider { 82 | 83 | @State static var menus: [Menu] = [ 84 | Menu(id: 0, name: "Music", next: true), 85 | Menu(id: 1, name: "Photos", next: true), 86 | ] 87 | 88 | @State static var menuIndex : Int = 0 89 | 90 | static var previews: some View { 91 | WheelView(menus: $menus, menuIndex: $menuIndex) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /images/xcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d1v1b/iPodClassicUI/4c8353cb2741fb7255ca121bd777d63403364820/images/xcode.png --------------------------------------------------------------------------------