├── .gitignore ├── assets └── presentation.png ├── readme.md ├── sidebarMenu.xcodeproj └── project.pbxproj └── sidebarMenu ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json ├── bgSlide.colorset │ └── Contents.json ├── selectTab.colorset │ └── Contents.json ├── slide1.imageset │ ├── Contents.json │ └── vecteezy_3d-minimal-notification-bell-icon-with-color-objects_7158460.jpg ├── slide2.imageset │ ├── Contents.json │ └── vecteezy_unique-realistic-3d-cute-icon-bubble-megaphone-isolated-on_8544392.jpg ├── slide3.imageset │ ├── Contents.json │ └── vecteezy_3d-alarm-clock-on-pastel-pink-background-pink-watch-minimal_7810742.jpg ├── slide4.imageset │ ├── Contents.json │ └── vecteezy_stock-vector-3d-note-book-pencil-check-icon-isolated_7508869.jpg └── slide5.imageset │ ├── Contents.json │ └── vecteezy_calendar-icon-check-sign-realistic-3d-web_6570666.jpg ├── ContentView.swift ├── Preview Content └── Preview Assets.xcassets │ └── Contents.json ├── sideMenu.swift ├── sidebarMenuApp.swift └── slider.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode user state files 2 | **/*.xcodeproj/project.xcworkspace/xcuserdata/* 3 | 4 | # Xcode scheme management files 5 | **/*.xcodeproj/xcuserdata/*/xcschemes/xcschememanagement.plist 6 | 7 | # Xcode shared data 8 | **/*.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist 9 | 10 | # Breakpoints 11 | **/*.xcodeproj/xcuserdata/*.xcuserdatad 12 | 13 | # Xcode workspacedata 14 | *.xcworkspacedata 15 | 16 | # SO 17 | *.DS_Store 18 | 19 | # Files configuration 20 | *.xcuserdatad 21 | xcshareddata -------------------------------------------------------------------------------- /assets/presentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierre-juarez/sidebar_menu/c2f948016dbf65a191fb117ea3e880016279aa15/assets/presentation.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Sidebar Swipe from Edge Gesture 🥳 2 | 3 | _Custom Animated Side Menu using SwiftUI: Swipe-from-Edge Gesture._ 4 | 5 | ## Presentation 6 | 7 | ![Desktop Version](assets/presentation.png?raw=true "Presentation") 8 | 9 | ## Credits 10 | 11 | ⌨️ Developed with ♥️ by [Pierre Juarez](https://www.linkedin.com/in/pierre-juarez/) 😊 -------------------------------------------------------------------------------- /sidebarMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5594A5522A3D39210076C85B /* sidebarMenuApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5594A5512A3D39210076C85B /* sidebarMenuApp.swift */; }; 11 | 5594A5542A3D39210076C85B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5594A5532A3D39210076C85B /* ContentView.swift */; }; 12 | 5594A5562A3D39230076C85B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5594A5552A3D39230076C85B /* Assets.xcassets */; }; 13 | 5594A5592A3D39230076C85B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5594A5582A3D39230076C85B /* Preview Assets.xcassets */; }; 14 | 5594A5602A3D5A980076C85B /* sideMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5594A55F2A3D5A980076C85B /* sideMenu.swift */; }; 15 | 5594A5662A3D5BDD0076C85B /* slider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5594A5652A3D5BDD0076C85B /* slider.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 5594A54E2A3D39210076C85B /* sidebarMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = sidebarMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 5594A5512A3D39210076C85B /* sidebarMenuApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sidebarMenuApp.swift; sourceTree = ""; }; 21 | 5594A5532A3D39210076C85B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 22 | 5594A5552A3D39230076C85B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 23 | 5594A5582A3D39230076C85B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 24 | 5594A55F2A3D5A980076C85B /* sideMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sideMenu.swift; sourceTree = ""; }; 25 | 5594A5652A3D5BDD0076C85B /* slider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = slider.swift; sourceTree = ""; }; 26 | /* End PBXFileReference section */ 27 | 28 | /* Begin PBXFrameworksBuildPhase section */ 29 | 5594A54B2A3D39210076C85B /* Frameworks */ = { 30 | isa = PBXFrameworksBuildPhase; 31 | buildActionMask = 2147483647; 32 | files = ( 33 | ); 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXFrameworksBuildPhase section */ 37 | 38 | /* Begin PBXGroup section */ 39 | 5594A5452A3D39210076C85B = { 40 | isa = PBXGroup; 41 | children = ( 42 | 5594A5502A3D39210076C85B /* sidebarMenu */, 43 | 5594A54F2A3D39210076C85B /* Products */, 44 | ); 45 | sourceTree = ""; 46 | }; 47 | 5594A54F2A3D39210076C85B /* Products */ = { 48 | isa = PBXGroup; 49 | children = ( 50 | 5594A54E2A3D39210076C85B /* sidebarMenu.app */, 51 | ); 52 | name = Products; 53 | sourceTree = ""; 54 | }; 55 | 5594A5502A3D39210076C85B /* sidebarMenu */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | 5594A5512A3D39210076C85B /* sidebarMenuApp.swift */, 59 | 5594A5532A3D39210076C85B /* ContentView.swift */, 60 | 5594A5552A3D39230076C85B /* Assets.xcassets */, 61 | 5594A5572A3D39230076C85B /* Preview Content */, 62 | 5594A55F2A3D5A980076C85B /* sideMenu.swift */, 63 | 5594A5652A3D5BDD0076C85B /* slider.swift */, 64 | ); 65 | path = sidebarMenu; 66 | sourceTree = ""; 67 | }; 68 | 5594A5572A3D39230076C85B /* Preview Content */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 5594A5582A3D39230076C85B /* Preview Assets.xcassets */, 72 | ); 73 | path = "Preview Content"; 74 | sourceTree = ""; 75 | }; 76 | /* End PBXGroup section */ 77 | 78 | /* Begin PBXNativeTarget section */ 79 | 5594A54D2A3D39210076C85B /* sidebarMenu */ = { 80 | isa = PBXNativeTarget; 81 | buildConfigurationList = 5594A55C2A3D39230076C85B /* Build configuration list for PBXNativeTarget "sidebarMenu" */; 82 | buildPhases = ( 83 | 5594A54A2A3D39210076C85B /* Sources */, 84 | 5594A54B2A3D39210076C85B /* Frameworks */, 85 | 5594A54C2A3D39210076C85B /* Resources */, 86 | ); 87 | buildRules = ( 88 | ); 89 | dependencies = ( 90 | ); 91 | name = sidebarMenu; 92 | productName = sidebarMenu; 93 | productReference = 5594A54E2A3D39210076C85B /* sidebarMenu.app */; 94 | productType = "com.apple.product-type.application"; 95 | }; 96 | /* End PBXNativeTarget section */ 97 | 98 | /* Begin PBXProject section */ 99 | 5594A5462A3D39210076C85B /* Project object */ = { 100 | isa = PBXProject; 101 | attributes = { 102 | BuildIndependentTargetsInParallel = 1; 103 | LastSwiftUpdateCheck = 1400; 104 | LastUpgradeCheck = 1400; 105 | TargetAttributes = { 106 | 5594A54D2A3D39210076C85B = { 107 | CreatedOnToolsVersion = 14.0.1; 108 | }; 109 | }; 110 | }; 111 | buildConfigurationList = 5594A5492A3D39210076C85B /* Build configuration list for PBXProject "sidebarMenu" */; 112 | compatibilityVersion = "Xcode 14.0"; 113 | developmentRegion = en; 114 | hasScannedForEncodings = 0; 115 | knownRegions = ( 116 | en, 117 | Base, 118 | ); 119 | mainGroup = 5594A5452A3D39210076C85B; 120 | productRefGroup = 5594A54F2A3D39210076C85B /* Products */; 121 | projectDirPath = ""; 122 | projectRoot = ""; 123 | targets = ( 124 | 5594A54D2A3D39210076C85B /* sidebarMenu */, 125 | ); 126 | }; 127 | /* End PBXProject section */ 128 | 129 | /* Begin PBXResourcesBuildPhase section */ 130 | 5594A54C2A3D39210076C85B /* Resources */ = { 131 | isa = PBXResourcesBuildPhase; 132 | buildActionMask = 2147483647; 133 | files = ( 134 | 5594A5592A3D39230076C85B /* Preview Assets.xcassets in Resources */, 135 | 5594A5562A3D39230076C85B /* Assets.xcassets in Resources */, 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | /* End PBXResourcesBuildPhase section */ 140 | 141 | /* Begin PBXSourcesBuildPhase section */ 142 | 5594A54A2A3D39210076C85B /* Sources */ = { 143 | isa = PBXSourcesBuildPhase; 144 | buildActionMask = 2147483647; 145 | files = ( 146 | 5594A5542A3D39210076C85B /* ContentView.swift in Sources */, 147 | 5594A5522A3D39210076C85B /* sidebarMenuApp.swift in Sources */, 148 | 5594A5662A3D5BDD0076C85B /* slider.swift in Sources */, 149 | 5594A5602A3D5A980076C85B /* sideMenu.swift in Sources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXSourcesBuildPhase section */ 154 | 155 | /* Begin XCBuildConfiguration section */ 156 | 5594A55A2A3D39230076C85B /* Debug */ = { 157 | isa = XCBuildConfiguration; 158 | buildSettings = { 159 | ALWAYS_SEARCH_USER_PATHS = NO; 160 | CLANG_ANALYZER_NONNULL = YES; 161 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 162 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 163 | CLANG_ENABLE_MODULES = YES; 164 | CLANG_ENABLE_OBJC_ARC = YES; 165 | CLANG_ENABLE_OBJC_WEAK = YES; 166 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 167 | CLANG_WARN_BOOL_CONVERSION = YES; 168 | CLANG_WARN_COMMA = YES; 169 | CLANG_WARN_CONSTANT_CONVERSION = YES; 170 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 171 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 172 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 173 | CLANG_WARN_EMPTY_BODY = YES; 174 | CLANG_WARN_ENUM_CONVERSION = YES; 175 | CLANG_WARN_INFINITE_RECURSION = YES; 176 | CLANG_WARN_INT_CONVERSION = YES; 177 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 178 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 179 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 180 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 181 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 182 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 183 | CLANG_WARN_STRICT_PROTOTYPES = YES; 184 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 185 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 186 | CLANG_WARN_UNREACHABLE_CODE = YES; 187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 188 | COPY_PHASE_STRIP = NO; 189 | DEBUG_INFORMATION_FORMAT = dwarf; 190 | ENABLE_STRICT_OBJC_MSGSEND = YES; 191 | ENABLE_TESTABILITY = YES; 192 | GCC_C_LANGUAGE_STANDARD = gnu11; 193 | GCC_DYNAMIC_NO_PIC = NO; 194 | GCC_NO_COMMON_BLOCKS = YES; 195 | GCC_OPTIMIZATION_LEVEL = 0; 196 | GCC_PREPROCESSOR_DEFINITIONS = ( 197 | "DEBUG=1", 198 | "$(inherited)", 199 | ); 200 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 201 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 202 | GCC_WARN_UNDECLARED_SELECTOR = YES; 203 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 204 | GCC_WARN_UNUSED_FUNCTION = YES; 205 | GCC_WARN_UNUSED_VARIABLE = YES; 206 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 207 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 208 | MTL_FAST_MATH = YES; 209 | ONLY_ACTIVE_ARCH = YES; 210 | SDKROOT = iphoneos; 211 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 212 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 213 | }; 214 | name = Debug; 215 | }; 216 | 5594A55B2A3D39230076C85B /* Release */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | ALWAYS_SEARCH_USER_PATHS = NO; 220 | CLANG_ANALYZER_NONNULL = YES; 221 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 223 | CLANG_ENABLE_MODULES = YES; 224 | CLANG_ENABLE_OBJC_ARC = YES; 225 | CLANG_ENABLE_OBJC_WEAK = YES; 226 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 227 | CLANG_WARN_BOOL_CONVERSION = YES; 228 | CLANG_WARN_COMMA = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INFINITE_RECURSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 238 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 239 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 241 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 242 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 243 | CLANG_WARN_STRICT_PROTOTYPES = YES; 244 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 245 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 246 | CLANG_WARN_UNREACHABLE_CODE = YES; 247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 248 | COPY_PHASE_STRIP = NO; 249 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 250 | ENABLE_NS_ASSERTIONS = NO; 251 | ENABLE_STRICT_OBJC_MSGSEND = YES; 252 | GCC_C_LANGUAGE_STANDARD = gnu11; 253 | GCC_NO_COMMON_BLOCKS = YES; 254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 256 | GCC_WARN_UNDECLARED_SELECTOR = YES; 257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 258 | GCC_WARN_UNUSED_FUNCTION = YES; 259 | GCC_WARN_UNUSED_VARIABLE = YES; 260 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 261 | MTL_ENABLE_DEBUG_INFO = NO; 262 | MTL_FAST_MATH = YES; 263 | SDKROOT = iphoneos; 264 | SWIFT_COMPILATION_MODE = wholemodule; 265 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 266 | VALIDATE_PRODUCT = YES; 267 | }; 268 | name = Release; 269 | }; 270 | 5594A55D2A3D39230076C85B /* Debug */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 274 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 275 | CODE_SIGN_STYLE = Automatic; 276 | CURRENT_PROJECT_VERSION = 1; 277 | DEVELOPMENT_ASSET_PATHS = "\"sidebarMenu/Preview Content\""; 278 | DEVELOPMENT_TEAM = ZTXUGF93M7; 279 | ENABLE_PREVIEWS = YES; 280 | GENERATE_INFOPLIST_FILE = YES; 281 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 282 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 283 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 284 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 285 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 286 | LD_RUNPATH_SEARCH_PATHS = ( 287 | "$(inherited)", 288 | "@executable_path/Frameworks", 289 | ); 290 | MARKETING_VERSION = 1.0; 291 | PRODUCT_BUNDLE_IDENTIFIER = swift.sidebarMenu; 292 | PRODUCT_NAME = "$(TARGET_NAME)"; 293 | SWIFT_EMIT_LOC_STRINGS = YES; 294 | SWIFT_VERSION = 5.0; 295 | TARGETED_DEVICE_FAMILY = "1,2"; 296 | }; 297 | name = Debug; 298 | }; 299 | 5594A55E2A3D39230076C85B /* Release */ = { 300 | isa = XCBuildConfiguration; 301 | buildSettings = { 302 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 303 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 304 | CODE_SIGN_STYLE = Automatic; 305 | CURRENT_PROJECT_VERSION = 1; 306 | DEVELOPMENT_ASSET_PATHS = "\"sidebarMenu/Preview Content\""; 307 | DEVELOPMENT_TEAM = ZTXUGF93M7; 308 | ENABLE_PREVIEWS = YES; 309 | GENERATE_INFOPLIST_FILE = YES; 310 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 311 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 312 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 313 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 314 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 315 | LD_RUNPATH_SEARCH_PATHS = ( 316 | "$(inherited)", 317 | "@executable_path/Frameworks", 318 | ); 319 | MARKETING_VERSION = 1.0; 320 | PRODUCT_BUNDLE_IDENTIFIER = swift.sidebarMenu; 321 | PRODUCT_NAME = "$(TARGET_NAME)"; 322 | SWIFT_EMIT_LOC_STRINGS = YES; 323 | SWIFT_VERSION = 5.0; 324 | TARGETED_DEVICE_FAMILY = "1,2"; 325 | }; 326 | name = Release; 327 | }; 328 | /* End XCBuildConfiguration section */ 329 | 330 | /* Begin XCConfigurationList section */ 331 | 5594A5492A3D39210076C85B /* Build configuration list for PBXProject "sidebarMenu" */ = { 332 | isa = XCConfigurationList; 333 | buildConfigurations = ( 334 | 5594A55A2A3D39230076C85B /* Debug */, 335 | 5594A55B2A3D39230076C85B /* Release */, 336 | ); 337 | defaultConfigurationIsVisible = 0; 338 | defaultConfigurationName = Release; 339 | }; 340 | 5594A55C2A3D39230076C85B /* Build configuration list for PBXNativeTarget "sidebarMenu" */ = { 341 | isa = XCConfigurationList; 342 | buildConfigurations = ( 343 | 5594A55D2A3D39230076C85B /* Debug */, 344 | 5594A55E2A3D39230076C85B /* Release */, 345 | ); 346 | defaultConfigurationIsVisible = 0; 347 | defaultConfigurationName = Release; 348 | }; 349 | /* End XCConfigurationList section */ 350 | }; 351 | rootObject = 5594A5462A3D39210076C85B /* Project object */; 352 | } 353 | -------------------------------------------------------------------------------- /sidebarMenu/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 | -------------------------------------------------------------------------------- /sidebarMenu/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 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/bgSlide.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x49", 9 | "green" : "0x25", 10 | "red" : "0x22" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x49", 27 | "green" : "0x25", 28 | "red" : "0x22" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | }, 38 | "properties" : { 39 | "localizable" : true 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/selectTab.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x60", 9 | "green" : "0x3A", 10 | "red" : "0x2A" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x60", 27 | "green" : "0x3A", 28 | "red" : "0x2A" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "vecteezy_3d-minimal-notification-bell-icon-with-color-objects_7158460.jpg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide1.imageset/vecteezy_3d-minimal-notification-bell-icon-with-color-objects_7158460.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierre-juarez/sidebar_menu/c2f948016dbf65a191fb117ea3e880016279aa15/sidebarMenu/Assets.xcassets/slide1.imageset/vecteezy_3d-minimal-notification-bell-icon-with-color-objects_7158460.jpg -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "vecteezy_unique-realistic-3d-cute-icon-bubble-megaphone-isolated-on_8544392.jpg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide2.imageset/vecteezy_unique-realistic-3d-cute-icon-bubble-megaphone-isolated-on_8544392.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierre-juarez/sidebar_menu/c2f948016dbf65a191fb117ea3e880016279aa15/sidebarMenu/Assets.xcassets/slide2.imageset/vecteezy_unique-realistic-3d-cute-icon-bubble-megaphone-isolated-on_8544392.jpg -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "vecteezy_3d-alarm-clock-on-pastel-pink-background-pink-watch-minimal_7810742.jpg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide3.imageset/vecteezy_3d-alarm-clock-on-pastel-pink-background-pink-watch-minimal_7810742.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierre-juarez/sidebar_menu/c2f948016dbf65a191fb117ea3e880016279aa15/sidebarMenu/Assets.xcassets/slide3.imageset/vecteezy_3d-alarm-clock-on-pastel-pink-background-pink-watch-minimal_7810742.jpg -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "vecteezy_stock-vector-3d-note-book-pencil-check-icon-isolated_7508869.jpg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide4.imageset/vecteezy_stock-vector-3d-note-book-pencil-check-icon-isolated_7508869.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierre-juarez/sidebar_menu/c2f948016dbf65a191fb117ea3e880016279aa15/sidebarMenu/Assets.xcassets/slide4.imageset/vecteezy_stock-vector-3d-note-book-pencil-check-icon-isolated_7508869.jpg -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "vecteezy_calendar-icon-check-sign-realistic-3d-web_6570666.jpg", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sidebarMenu/Assets.xcassets/slide5.imageset/vecteezy_calendar-icon-check-sign-realistic-3d-web_6570666.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierre-juarez/sidebar_menu/c2f948016dbf65a191fb117ea3e880016279aa15/sidebarMenu/Assets.xcassets/slide5.imageset/vecteezy_calendar-icon-check-sign-realistic-3d-web_6570666.jpg -------------------------------------------------------------------------------- /sidebarMenu/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // sidebarMenu 4 | // 5 | // Created by Pierre Juarez U. on 16/06/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | 12 | @State var show = false 13 | let mindarg : CGFloat = 100 14 | 15 | var body: some View { 16 | ZStack{ 17 | 18 | Button { 19 | withAnimation { 20 | show = true 21 | } 22 | } label: { 23 | Text("Show") 24 | } 25 | 26 | 27 | sideMenu() 28 | .offset(x: show ? 0 : -270) 29 | .gesture( 30 | DragGesture() 31 | .onEnded({ value in 32 | let shoulsShow = value.translation.width > self.mindarg 33 | withAnimation { 34 | show = shoulsShow 35 | } 36 | }) 37 | ) 38 | } 39 | 40 | } 41 | } 42 | 43 | struct ContentView_Previews: PreviewProvider { 44 | static var previews: some View { 45 | ContentView() 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /sidebarMenu/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sidebarMenu/sideMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // sideMenu.swift 3 | // sidebarMenu 4 | // 5 | // Created by Pierre Juarez U. on 16/06/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | enum tabIcon: String{ 11 | case Home 12 | case Card 13 | case Favorite 14 | case Purchases 15 | case Notification 16 | } 17 | 18 | struct sidebar: Identifiable { 19 | var id = UUID() 20 | var icon: String 21 | var title: String 22 | var index: Int 23 | var tab: tabIcon 24 | } 25 | 26 | let sidebarItems = [ 27 | sidebar(icon: "house.fill", title: "Home", index: 0, tab: .Home), 28 | sidebar(icon: "creditcard.fill", title: "Card", index: 1, tab: .Card), 29 | sidebar(icon: "heart.fill", title: "Favorite", index: 2, tab: .Favorite), 30 | sidebar(icon: "cart.fill.badge.plus", title: "Purchases", index: 3, tab: .Purchases), 31 | sidebar(icon: "bell.badge.fill", title: "Notification", index: 4, tab: .Notification) 32 | ] 33 | 34 | struct sideMenu: View { 35 | 36 | @State var selectedItem: tabIcon = .Home 37 | @State var yOffset: CGFloat = 0 38 | 39 | var body: some View { 40 | ZStack{ 41 | Color("bgSlide") 42 | .frame(width: 266) 43 | .mask(RoundedRectangle(cornerRadius: 10, style: .continuous)) 44 | VStack(alignment: .leading){ 45 | VStack(alignment: .leading){ 46 | userProfile() 47 | tabView(selectedItem: $selectedItem, yOffset: $yOffset) 48 | 49 | 50 | }.padding(.leading, 15) 51 | Spacer() 52 | divider() 53 | slider() 54 | HStack{ 55 | Text("Learn more about the app") 56 | .padding(.leading) 57 | Image(systemName: "questionmark.circle") 58 | } 59 | .foregroundColor(.white) 60 | .padding(.top, 5) 61 | Spacer() 62 | HStack{ 63 | Bicon(icon: "moon.zzz.fill") 64 | Spacer() 65 | Text("Shoping") 66 | .foregroundColor(.white) 67 | Spacer() 68 | Bicon(icon: "gearshape.fill") 69 | } 70 | .padding(.bottom, 20) 71 | .frame(width: 230, height: 90) 72 | .padding(.leading, 17) 73 | 74 | } 75 | 76 | } 77 | .ignoresSafeArea() 78 | .frame(maxHeight: .infinity) 79 | .frame(maxWidth: .infinity, alignment: .leading) 80 | } 81 | } 82 | 83 | struct sideMenu_Previews: PreviewProvider { 84 | static var previews: some View { 85 | sideMenu() 86 | } 87 | } 88 | 89 | struct userProfile: View { 90 | var body: some View { 91 | HStack{ 92 | Circle() 93 | .frame(width: 65, height: 65) 94 | .foregroundColor(.white) 95 | VStack{ 96 | RoundedRectangle(cornerRadius: 3, style: .continuous) 97 | .frame(width: 100, height: 14) 98 | RoundedRectangle(cornerRadius: 3, style: .continuous) 99 | .frame(width: 80, height: 7) 100 | .opacity(0.5) 101 | RoundedRectangle(cornerRadius: 3, style: .continuous) 102 | .frame(width: 52, height: 7) 103 | .opacity(0.5) 104 | 105 | } 106 | }.foregroundColor(.white) 107 | .padding(.top, 60) 108 | } 109 | } 110 | 111 | struct tabView: View { 112 | 113 | @Binding var selectedItem: tabIcon 114 | @Binding var yOffset: CGFloat 115 | @State var isAnimation = false 116 | 117 | var body: some View{ 118 | ZStack(alignment: .leading){ 119 | Rectangle() 120 | .frame(width: isAnimation ? 7 : 230, height: 45) 121 | .foregroundColor(Color("selectTab")) 122 | .cornerRadius(7) 123 | .offset(y: yOffset) 124 | .padding(.vertical, 8) 125 | .padding(.horizontal, 5) 126 | .offset(y: -125) 127 | .offset(x: -20) 128 | .animation(.default, value: isAnimation) 129 | 130 | VStack(spacing: 0){ 131 | ForEach(sidebarItems) { item in 132 | Button { 133 | withAnimation { 134 | isAnimation = true 135 | } 136 | 137 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.3){ 138 | withAnimation { 139 | selectedItem = item.tab 140 | yOffset = CGFloat(item.index) * 70 141 | } 142 | } 143 | 144 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.6){ 145 | withAnimation { 146 | isAnimation = false 147 | } 148 | } 149 | 150 | } label: { 151 | HStack{ 152 | ZStack{ 153 | Circle() 154 | .frame(width: 39, height: 40) 155 | .foregroundStyle(.ultraThinMaterial) 156 | Image(systemName: item.icon) 157 | .foregroundColor(.white) 158 | } 159 | Text(item.title) 160 | .bold() 161 | .font(.title3) 162 | .foregroundColor(.white) 163 | .padding(.leading, 10) 164 | Spacer() 165 | } 166 | .padding(.top, 30) 167 | 168 | } 169 | 170 | } 171 | } 172 | .frame(width: 240, height: 330) 173 | 174 | 175 | } 176 | } 177 | } 178 | 179 | struct divider: View { 180 | var body: some View{ 181 | Rectangle() 182 | .frame(width: 266, height: 1) 183 | .foregroundColor(.gray.opacity(0.4)) 184 | .padding(.top,30) 185 | } 186 | 187 | } 188 | 189 | struct Bicon: View{ 190 | 191 | var icon = "" 192 | 193 | var body: some View{ 194 | ZStack{ 195 | Circle() 196 | .frame(width: 48, height: 48) 197 | .foregroundStyle(.ultraThinMaterial) 198 | Image(systemName: icon) 199 | .foregroundColor(.white) 200 | } 201 | } 202 | 203 | } 204 | -------------------------------------------------------------------------------- /sidebarMenu/sidebarMenuApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // sidebarMenuApp.swift 3 | // sidebarMenu 4 | // 5 | // Created by Pierre Juarez U. on 16/06/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct sidebarMenuApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sidebarMenu/slider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // slider.swift 3 | // sidebarMenu 4 | // 5 | // Created by Pierre Juarez U. on 16/06/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct slider: View { 11 | 12 | @State var selectedIndex = 0 13 | let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect() 14 | 15 | var body: some View { 16 | TabView(selection: $selectedIndex) { 17 | imageView(image: "slide1") 18 | .tag(1) 19 | imageView(image: "slide2") 20 | .tag(2) 21 | imageView(image: "slide3") 22 | .tag(3) 23 | imageView(image: "slide4") 24 | .tag(4) 25 | imageView(image: "slide5") 26 | .tag(5) 27 | }.tabViewStyle(PageTabViewStyle()) 28 | .offset(x: -10) 29 | .frame(width: 266, height: 175) 30 | .padding(.top, 10) 31 | .onReceive(timer) { _ in 32 | withAnimation { 33 | selectedIndex = selectedIndex == 5 ? 0 : selectedIndex + 1 34 | } 35 | } 36 | } 37 | } 38 | 39 | struct slider_Previews: PreviewProvider { 40 | static var previews: some View { 41 | slider() 42 | } 43 | } 44 | 45 | struct imageView: View { 46 | 47 | var image = "" 48 | 49 | var body: some View{ 50 | Image(image) 51 | .resizable() 52 | .scaledToFill() 53 | .frame(width: 230, height: 157) 54 | .clipped() 55 | .cornerRadius(10) 56 | .padding(.leading, 15) 57 | } 58 | } 59 | --------------------------------------------------------------------------------