├── PetalMenu ├── PetalMenu │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── PetalMenuApp.swift │ ├── ContentView.swift │ ├── ColorPalette.swift │ ├── SelectAThemeButton.swift │ └── PetalMenu.swift └── PetalMenu.xcodeproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── christian.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── xcuserdata │ └── christian.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist │ └── project.pbxproj ├── README.md └── .gitignore /PetalMenu/PetalMenu/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu.xcodeproj/project.xcworkspace/xcuserdata/christian.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bodhichristian/petal-menu/HEAD/PetalMenu/PetalMenu.xcodeproj/project.xcworkspace/xcuserdata/christian.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/PetalMenuApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PetalMenuApp.swift 3 | // PetalMenu 4 | // 5 | // Created by christian on 12/6/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct PetalMenuApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu.xcodeproj/xcuserdata/christian.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PetalMenu.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PetalMenu 2 | A flowering menu built with SwiftUI. 3 | 4 | Using .rotationEffect and a .bouncy animation, PetalMenu expands and collapses to provide users a unique way to make a selection. Accessibility modifiers are in place to provide clear use to VoiceOver users, and hide decorative elements. 5 | 6 | In this sample app, PetalMenu is used as a theme picker. It takes an array of colors, and a binding to a selectedColor value, and ContentView renders a background gradient based on the selection. The ColorPalette object provides arrays of Color in multicolor, warm, cool, and monochromatic styles. 7 | 8 | ![Petals Showcase 001](https://github.com/bodhichristian/PetalMenu/assets/110639779/542846c3-cf1c-4958-96e1-7554cde218e9) 9 | 10 | https://github.com/bodhichristian/PetalMenu/assets/110639779/c6f52cd3-a5fc-4cd8-aeec-04cf5945c3d8 11 | 12 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // PetalMenu 4 | // 5 | // Created by christian on 12/6/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | let colors = ColorPalette.multicolor 12 | 13 | var backgroundGradient: LinearGradient { 14 | LinearGradient( 15 | colors: [selectedColor.opacity(0.2), 16 | selectedColor.opacity(0.5), 17 | selectedColor 18 | ], 19 | startPoint: .top, 20 | endPoint: .bottom 21 | ) 22 | } 23 | 24 | @State private var selectedColor: Color = .purple 25 | 26 | var body: some View { 27 | ZStack { 28 | backgroundGradient 29 | .ignoresSafeArea() 30 | 31 | PetalMenu(colors: colors, selectedColor: $selectedColor) 32 | 33 | } 34 | } 35 | } 36 | 37 | #Preview { 38 | ContentView() 39 | } 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/ColorPalette.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorPalette.swift 3 | // PetalMenu 4 | // 5 | // Created by christian on 12/6/23. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct ColorPalette { 12 | static let multicolor: [Color] = [.orange, .yellow, .green, .cyan, .blue, .purple, .pink, .red] 13 | 14 | static let cool: [Color] = [.blue, .cyan, .teal, .mint, .green, .purple, .indigo] 15 | 16 | static let warm: [Color] = [.red, .white, .orange, .white, .yellow, .white, .pink, .white] 17 | 18 | static let monochromatic: [Color] = [ 19 | Color(hue: 0, saturation: 0, brightness: 1), 20 | Color(hue: 0, saturation: 0, brightness: 0.8), 21 | Color(hue: 0, saturation: 0, brightness: 0.7), 22 | Color(hue: 0, saturation: 0, brightness: 0.5), 23 | Color(hue: 0, saturation: 0, brightness: 0.4), 24 | Color(hue: 0, saturation: 0, brightness: 0.3), 25 | Color(hue: 0, saturation: 0, brightness: 0.2), 26 | Color(hue: 0, saturation: 0, brightness: 0.1), 27 | ] 28 | 29 | } 30 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/SelectAThemeButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelectAThemeButton.swift 3 | // PetalMenu 4 | // 5 | // Created by christian on 12/6/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SelectAThemeButton: View { 11 | let colorTheme: Color 12 | 13 | var gradient: LinearGradient { 14 | LinearGradient(colors: [colorTheme.opacity(0.6), colorTheme ], startPoint: .top, endPoint: .bottom) 15 | } 16 | 17 | @Binding var menuOpen: Bool 18 | 19 | var body: some View { 20 | ZStack { 21 | // Button base layer 22 | Capsule() 23 | .foregroundStyle(gradient) 24 | .frame(width: 200, height: 44) 25 | .shadow(color: menuOpen ? .black : .black.opacity(0.2), radius: menuOpen ? 2 : 10, y: menuOpen ? 0 : 7) 26 | 27 | // Button Text 28 | Text("Select a theme") 29 | .font(.headline) 30 | .foregroundStyle(.white) 31 | .padding() 32 | 33 | } 34 | 35 | // Open menu 36 | .onTapGesture { 37 | withAnimation(.bouncy){ 38 | menuOpen.toggle() 39 | } 40 | } 41 | 42 | } 43 | } 44 | 45 | #Preview { 46 | SelectAThemeButton(colorTheme: .blue, menuOpen: .constant(false)) 47 | } 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | .DS_Store 6 | 7 | ## User settings 8 | xcuserdata/ 9 | 10 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 11 | *.xcscmblueprint 12 | *.xccheckout 13 | 14 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 15 | build/ 16 | DerivedData/ 17 | *.moved-aside 18 | *.pbxuser 19 | !default.pbxuser 20 | *.mode1v3 21 | !default.mode1v3 22 | *.mode2v3 23 | !default.mode2v3 24 | *.perspectivev3 25 | !default.perspectivev3 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | 30 | ## App packaging 31 | *.ipa 32 | *.dSYM.zip 33 | *.dSYM 34 | 35 | ## Playgrounds 36 | timeline.xctimeline 37 | playground.xcworkspace 38 | 39 | # Swift Package Manager 40 | # 41 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 42 | # Packages/ 43 | # Package.pins 44 | # Package.resolved 45 | # *.xcodeproj 46 | # 47 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 48 | # hence it is not needed unless you have added a package configuration file to your project 49 | # .swiftpm 50 | 51 | .build/ 52 | 53 | # CocoaPods 54 | # 55 | # We recommend against adding the Pods directory to your .gitignore. However 56 | # you should judge for yourself, the pros and cons are mentioned at: 57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 58 | # 59 | # Pods/ 60 | # 61 | # Add this line if you want to avoid checking in source code from the Xcode workspace 62 | # *.xcworkspace 63 | 64 | # Carthage 65 | # 66 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 67 | # Carthage/Checkouts 68 | 69 | Carthage/Build/ 70 | 71 | # Accio dependency management 72 | Dependencies/ 73 | .accio/ 74 | 75 | # fastlane 76 | # 77 | # It is recommended to not store the screenshots in the git repo. 78 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 79 | # For more information about the recommended setup visit: 80 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 81 | 82 | fastlane/report.xml 83 | fastlane/Preview.html 84 | fastlane/screenshots/**/*.png 85 | fastlane/test_output 86 | 87 | # Code Injection 88 | # 89 | # After new code Injection tools there's a generated folder /iOSInjectionProject 90 | # https://github.com/johnno1962/injectionforxcode 91 | 92 | iOSInjectionProject/ -------------------------------------------------------------------------------- /PetalMenu/PetalMenu/PetalMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PetalMenu.swift 3 | // PetalMenu 4 | // 5 | // Created by christian on 12/6/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct PetalMenu: View { 11 | let colors: [Color] 12 | 13 | // Get petal rotation angle 14 | var degreesOffset: Double { 15 | 360.0 / Double(colors.count) 16 | } 17 | 18 | @Binding var selectedColor: Color 19 | @State private var menuOpen: Bool = false 20 | 21 | var body: some View { 22 | GeometryReader { geo in 23 | ZStack { 24 | 25 | // Tap background to close menu 26 | Rectangle() 27 | .foregroundStyle(.white.opacity(0.1)) 28 | .ignoresSafeArea() 29 | .onTapGesture { 30 | withAnimation(.bouncy){ 31 | menuOpen = false 32 | } 33 | } 34 | 35 | // MARK: Accessibility - Close Menu 36 | .accessibilityLabel("Cancel selection.") 37 | .accessibilityAddTraits(.isButton) 38 | .accessibilityHidden(!menuOpen) 39 | 40 | // Base layer 41 | Circle() 42 | .foregroundStyle(.thinMaterial) 43 | .shadow(radius: menuOpen ? 30 : /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/, y: 10) 44 | .frame( 45 | width: menuOpen 46 | ? geo.size.width * 0.9 47 | : geo.size.width * 0.4, 48 | height: geo.size.width * 0.9 49 | ) 50 | .position(x: geo.size.width / 2, y: geo.size.height / 2) 51 | .offset(y: -3) 52 | 53 | // MARK: Accessibility - Decorative Elememt 54 | .accessibilityHidden(true) 55 | 56 | // Petals 57 | ForEach(Array(colors.enumerated()), id: \.offset) { index, color in 58 | ZStack { 59 | Capsule() 60 | .foregroundStyle( 61 | LinearGradient( 62 | colors: [color, color, color.opacity(0.7)], 63 | startPoint: .top, 64 | endPoint: .bottom 65 | ) 66 | ) 67 | 68 | // Capsule height bound to menuOpen state 69 | // Resembles a circle when menuOpen == false 70 | .frame( 71 | width: geo.size.width * 0.25, 72 | height: menuOpen 73 | ? geo.size.width * 0.40 74 | : geo.size.width * 0.25) 75 | 76 | // Offset capsules when menuOpen == true 77 | .offset(y: menuOpen ? -geo.size.width * 0.2 : 0) 78 | 79 | // Add shadow when menuOpen == true 80 | .shadow( 81 | color: menuOpen 82 | ? .black.opacity(0.4) 83 | : .clear, 84 | radius: 5, 85 | y: 12 86 | ) 87 | 88 | // Rotate capsule in relationship to its color's offset 89 | .rotationEffect( 90 | .degrees(menuOpen 91 | ? (Double(index) * degreesOffset) 92 | : 0 ) 93 | ) 94 | 95 | // Update selected color 96 | .onTapGesture { 97 | withAnimation(.bouncy){ 98 | selectedColor = color 99 | menuOpen = false 100 | } 101 | } 102 | 103 | // MARK: Accessibility - Option Labels 104 | .accessibilityLabel("Option \(index + 1): \(color.description)") 105 | .accessibilityAddTraits(.isButton) 106 | .accessibilityHidden(!menuOpen) 107 | } 108 | } 109 | 110 | // Present selectedColor when menuOpen == false 111 | if !menuOpen { 112 | Circle() 113 | .frame(width: geo.size.width * 0.3) 114 | .foregroundStyle(menuOpen ? .clear : selectedColor) 115 | .position(x: geo.size.width / 2, y: geo.size.height / 2 - 3) 116 | .onTapGesture { 117 | withAnimation(.bouncy) { 118 | menuOpen = true 119 | } 120 | } 121 | 122 | // MARK: Accessibility - Open Menu 123 | .accessibilityLabel("Select a Color") 124 | .accessibilityAddTraits(.isButton) 125 | .accessibilityHidden(menuOpen) 126 | } 127 | 128 | } 129 | 130 | // Center in GeometryReader 131 | .position(x: geo.size.width / 2, y: geo.size.height / 2) 132 | 133 | } 134 | } 135 | } 136 | 137 | #Preview { 138 | PetalMenu(colors: ColorPalette.warm, selectedColor: .constant(.white)) 139 | } 140 | -------------------------------------------------------------------------------- /PetalMenu/PetalMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AA887C602B209659006A9218 /* PetalMenuApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA887C5F2B209659006A9218 /* PetalMenuApp.swift */; }; 11 | AA887C622B209659006A9218 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA887C612B209659006A9218 /* ContentView.swift */; }; 12 | AA887C642B20965B006A9218 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AA887C632B20965B006A9218 /* Assets.xcassets */; }; 13 | AA887C672B20965B006A9218 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AA887C662B20965B006A9218 /* Preview Assets.xcassets */; }; 14 | AA887C6E2B20967E006A9218 /* PetalMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA887C6D2B20967E006A9218 /* PetalMenu.swift */; }; 15 | AA887C702B209906006A9218 /* SelectAThemeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA887C6F2B209906006A9218 /* SelectAThemeButton.swift */; }; 16 | AAD6BD282B214576003663F1 /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAD6BD272B214576003663F1 /* ColorPalette.swift */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | AA887C5C2B209659006A9218 /* PetalMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PetalMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | AA887C5F2B209659006A9218 /* PetalMenuApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PetalMenuApp.swift; sourceTree = ""; }; 22 | AA887C612B209659006A9218 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 23 | AA887C632B20965B006A9218 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 24 | AA887C662B20965B006A9218 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 25 | AA887C6D2B20967E006A9218 /* PetalMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PetalMenu.swift; sourceTree = ""; }; 26 | AA887C6F2B209906006A9218 /* SelectAThemeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectAThemeButton.swift; sourceTree = ""; }; 27 | AAD6BD272B214576003663F1 /* ColorPalette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPalette.swift; sourceTree = ""; }; 28 | /* End PBXFileReference section */ 29 | 30 | /* Begin PBXFrameworksBuildPhase section */ 31 | AA887C592B209659006A9218 /* Frameworks */ = { 32 | isa = PBXFrameworksBuildPhase; 33 | buildActionMask = 2147483647; 34 | files = ( 35 | ); 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | /* End PBXFrameworksBuildPhase section */ 39 | 40 | /* Begin PBXGroup section */ 41 | AA887C532B209659006A9218 = { 42 | isa = PBXGroup; 43 | children = ( 44 | AA887C5E2B209659006A9218 /* PetalMenu */, 45 | AA887C5D2B209659006A9218 /* Products */, 46 | ); 47 | sourceTree = ""; 48 | }; 49 | AA887C5D2B209659006A9218 /* Products */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | AA887C5C2B209659006A9218 /* PetalMenu.app */, 53 | ); 54 | name = Products; 55 | sourceTree = ""; 56 | }; 57 | AA887C5E2B209659006A9218 /* PetalMenu */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | AA887C5F2B209659006A9218 /* PetalMenuApp.swift */, 61 | AA887C612B209659006A9218 /* ContentView.swift */, 62 | AA887C6D2B20967E006A9218 /* PetalMenu.swift */, 63 | AA887C6F2B209906006A9218 /* SelectAThemeButton.swift */, 64 | AAD6BD272B214576003663F1 /* ColorPalette.swift */, 65 | AA887C632B20965B006A9218 /* Assets.xcassets */, 66 | AA887C652B20965B006A9218 /* Preview Content */, 67 | ); 68 | path = PetalMenu; 69 | sourceTree = ""; 70 | }; 71 | AA887C652B20965B006A9218 /* Preview Content */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | AA887C662B20965B006A9218 /* Preview Assets.xcassets */, 75 | ); 76 | path = "Preview Content"; 77 | sourceTree = ""; 78 | }; 79 | /* End PBXGroup section */ 80 | 81 | /* Begin PBXNativeTarget section */ 82 | AA887C5B2B209659006A9218 /* PetalMenu */ = { 83 | isa = PBXNativeTarget; 84 | buildConfigurationList = AA887C6A2B20965B006A9218 /* Build configuration list for PBXNativeTarget "PetalMenu" */; 85 | buildPhases = ( 86 | AA887C582B209659006A9218 /* Sources */, 87 | AA887C592B209659006A9218 /* Frameworks */, 88 | AA887C5A2B209659006A9218 /* Resources */, 89 | ); 90 | buildRules = ( 91 | ); 92 | dependencies = ( 93 | ); 94 | name = PetalMenu; 95 | productName = PetalMenu; 96 | productReference = AA887C5C2B209659006A9218 /* PetalMenu.app */; 97 | productType = "com.apple.product-type.application"; 98 | }; 99 | /* End PBXNativeTarget section */ 100 | 101 | /* Begin PBXProject section */ 102 | AA887C542B209659006A9218 /* Project object */ = { 103 | isa = PBXProject; 104 | attributes = { 105 | BuildIndependentTargetsInParallel = 1; 106 | LastSwiftUpdateCheck = 1500; 107 | LastUpgradeCheck = 1500; 108 | TargetAttributes = { 109 | AA887C5B2B209659006A9218 = { 110 | CreatedOnToolsVersion = 15.0.1; 111 | }; 112 | }; 113 | }; 114 | buildConfigurationList = AA887C572B209659006A9218 /* Build configuration list for PBXProject "PetalMenu" */; 115 | compatibilityVersion = "Xcode 14.0"; 116 | developmentRegion = en; 117 | hasScannedForEncodings = 0; 118 | knownRegions = ( 119 | en, 120 | Base, 121 | ); 122 | mainGroup = AA887C532B209659006A9218; 123 | productRefGroup = AA887C5D2B209659006A9218 /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | AA887C5B2B209659006A9218 /* PetalMenu */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXResourcesBuildPhase section */ 133 | AA887C5A2B209659006A9218 /* Resources */ = { 134 | isa = PBXResourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | AA887C672B20965B006A9218 /* Preview Assets.xcassets in Resources */, 138 | AA887C642B20965B006A9218 /* Assets.xcassets in Resources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXResourcesBuildPhase section */ 143 | 144 | /* Begin PBXSourcesBuildPhase section */ 145 | AA887C582B209659006A9218 /* Sources */ = { 146 | isa = PBXSourcesBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | AAD6BD282B214576003663F1 /* ColorPalette.swift in Sources */, 150 | AA887C6E2B20967E006A9218 /* PetalMenu.swift in Sources */, 151 | AA887C622B209659006A9218 /* ContentView.swift in Sources */, 152 | AA887C602B209659006A9218 /* PetalMenuApp.swift in Sources */, 153 | AA887C702B209906006A9218 /* SelectAThemeButton.swift in Sources */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXSourcesBuildPhase section */ 158 | 159 | /* Begin XCBuildConfiguration section */ 160 | AA887C682B20965B006A9218 /* Debug */ = { 161 | isa = XCBuildConfiguration; 162 | buildSettings = { 163 | ALWAYS_SEARCH_USER_PATHS = NO; 164 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 165 | CLANG_ANALYZER_NONNULL = YES; 166 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 167 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 168 | CLANG_ENABLE_MODULES = YES; 169 | CLANG_ENABLE_OBJC_ARC = YES; 170 | CLANG_ENABLE_OBJC_WEAK = YES; 171 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 172 | CLANG_WARN_BOOL_CONVERSION = YES; 173 | CLANG_WARN_COMMA = YES; 174 | CLANG_WARN_CONSTANT_CONVERSION = YES; 175 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 178 | CLANG_WARN_EMPTY_BODY = YES; 179 | CLANG_WARN_ENUM_CONVERSION = YES; 180 | CLANG_WARN_INFINITE_RECURSION = YES; 181 | CLANG_WARN_INT_CONVERSION = YES; 182 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 183 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 184 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 185 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 186 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 187 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 188 | CLANG_WARN_STRICT_PROTOTYPES = YES; 189 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 190 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 191 | CLANG_WARN_UNREACHABLE_CODE = YES; 192 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 193 | COPY_PHASE_STRIP = NO; 194 | DEBUG_INFORMATION_FORMAT = dwarf; 195 | ENABLE_STRICT_OBJC_MSGSEND = YES; 196 | ENABLE_TESTABILITY = YES; 197 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 198 | GCC_C_LANGUAGE_STANDARD = gnu17; 199 | GCC_DYNAMIC_NO_PIC = NO; 200 | GCC_NO_COMMON_BLOCKS = YES; 201 | GCC_OPTIMIZATION_LEVEL = 0; 202 | GCC_PREPROCESSOR_DEFINITIONS = ( 203 | "DEBUG=1", 204 | "$(inherited)", 205 | ); 206 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 207 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 208 | GCC_WARN_UNDECLARED_SELECTOR = YES; 209 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 210 | GCC_WARN_UNUSED_FUNCTION = YES; 211 | GCC_WARN_UNUSED_VARIABLE = YES; 212 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 213 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 214 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 215 | MTL_FAST_MATH = YES; 216 | ONLY_ACTIVE_ARCH = YES; 217 | SDKROOT = iphoneos; 218 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 219 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 220 | }; 221 | name = Debug; 222 | }; 223 | AA887C692B20965B006A9218 /* Release */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 228 | CLANG_ANALYZER_NONNULL = YES; 229 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 230 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 231 | CLANG_ENABLE_MODULES = YES; 232 | CLANG_ENABLE_OBJC_ARC = YES; 233 | CLANG_ENABLE_OBJC_WEAK = YES; 234 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 235 | CLANG_WARN_BOOL_CONVERSION = YES; 236 | CLANG_WARN_COMMA = YES; 237 | CLANG_WARN_CONSTANT_CONVERSION = YES; 238 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 239 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 240 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 241 | CLANG_WARN_EMPTY_BODY = YES; 242 | CLANG_WARN_ENUM_CONVERSION = YES; 243 | CLANG_WARN_INFINITE_RECURSION = YES; 244 | CLANG_WARN_INT_CONVERSION = YES; 245 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 246 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 247 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 248 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 249 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 250 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 251 | CLANG_WARN_STRICT_PROTOTYPES = YES; 252 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 253 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 254 | CLANG_WARN_UNREACHABLE_CODE = YES; 255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 256 | COPY_PHASE_STRIP = NO; 257 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 258 | ENABLE_NS_ASSERTIONS = NO; 259 | ENABLE_STRICT_OBJC_MSGSEND = YES; 260 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 261 | GCC_C_LANGUAGE_STANDARD = gnu17; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 264 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 265 | GCC_WARN_UNDECLARED_SELECTOR = YES; 266 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 267 | GCC_WARN_UNUSED_FUNCTION = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 270 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 271 | MTL_ENABLE_DEBUG_INFO = NO; 272 | MTL_FAST_MATH = YES; 273 | SDKROOT = iphoneos; 274 | SWIFT_COMPILATION_MODE = wholemodule; 275 | VALIDATE_PRODUCT = YES; 276 | }; 277 | name = Release; 278 | }; 279 | AA887C6B2B20965B006A9218 /* Debug */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 283 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 284 | CODE_SIGN_STYLE = Automatic; 285 | CURRENT_PROJECT_VERSION = 1; 286 | DEVELOPMENT_ASSET_PATHS = "\"PetalMenu/Preview Content\""; 287 | DEVELOPMENT_TEAM = N6RF4M6NH8; 288 | ENABLE_PREVIEWS = YES; 289 | GENERATE_INFOPLIST_FILE = YES; 290 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 291 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 292 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 293 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 294 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 295 | LD_RUNPATH_SEARCH_PATHS = ( 296 | "$(inherited)", 297 | "@executable_path/Frameworks", 298 | ); 299 | MARKETING_VERSION = 1.0; 300 | PRODUCT_BUNDLE_IDENTIFIER = com.christianlavelle.PetalMenu; 301 | PRODUCT_NAME = "$(TARGET_NAME)"; 302 | SWIFT_EMIT_LOC_STRINGS = YES; 303 | SWIFT_VERSION = 5.0; 304 | TARGETED_DEVICE_FAMILY = "1,2"; 305 | }; 306 | name = Debug; 307 | }; 308 | AA887C6C2B20965B006A9218 /* Release */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 312 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 313 | CODE_SIGN_STYLE = Automatic; 314 | CURRENT_PROJECT_VERSION = 1; 315 | DEVELOPMENT_ASSET_PATHS = "\"PetalMenu/Preview Content\""; 316 | DEVELOPMENT_TEAM = N6RF4M6NH8; 317 | ENABLE_PREVIEWS = YES; 318 | GENERATE_INFOPLIST_FILE = YES; 319 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 320 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 321 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 322 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 323 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 324 | LD_RUNPATH_SEARCH_PATHS = ( 325 | "$(inherited)", 326 | "@executable_path/Frameworks", 327 | ); 328 | MARKETING_VERSION = 1.0; 329 | PRODUCT_BUNDLE_IDENTIFIER = com.christianlavelle.PetalMenu; 330 | PRODUCT_NAME = "$(TARGET_NAME)"; 331 | SWIFT_EMIT_LOC_STRINGS = YES; 332 | SWIFT_VERSION = 5.0; 333 | TARGETED_DEVICE_FAMILY = "1,2"; 334 | }; 335 | name = Release; 336 | }; 337 | /* End XCBuildConfiguration section */ 338 | 339 | /* Begin XCConfigurationList section */ 340 | AA887C572B209659006A9218 /* Build configuration list for PBXProject "PetalMenu" */ = { 341 | isa = XCConfigurationList; 342 | buildConfigurations = ( 343 | AA887C682B20965B006A9218 /* Debug */, 344 | AA887C692B20965B006A9218 /* Release */, 345 | ); 346 | defaultConfigurationIsVisible = 0; 347 | defaultConfigurationName = Release; 348 | }; 349 | AA887C6A2B20965B006A9218 /* Build configuration list for PBXNativeTarget "PetalMenu" */ = { 350 | isa = XCConfigurationList; 351 | buildConfigurations = ( 352 | AA887C6B2B20965B006A9218 /* Debug */, 353 | AA887C6C2B20965B006A9218 /* Release */, 354 | ); 355 | defaultConfigurationIsVisible = 0; 356 | defaultConfigurationName = Release; 357 | }; 358 | /* End XCConfigurationList section */ 359 | }; 360 | rootObject = AA887C542B209659006A9218 /* Project object */; 361 | } 362 | --------------------------------------------------------------------------------