├── .gitignore ├── README.md ├── demo ├── alert_modal.gif ├── animated_background.gif ├── circular_progress.gif ├── horizontal_slider.gif ├── long_press_button.gif ├── mesh_gradient_button.gif ├── movies_gradient_blur.gif ├── revealing_button.gif ├── scrolling_stack.gif ├── simple_picker.gif ├── tab_bar.gif └── vertical_scroll.gif ├── swiftystuff.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── aillo.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── aillo.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist └── swiftystuff ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ ├── Contents.json │ └── Logo.png ├── Contents.json ├── bgColor.colorset │ └── Contents.json ├── movies │ ├── Contents.json │ ├── chernobyl.imageset │ │ ├── Contents.json │ │ └── chernobyl.jpg │ ├── silo.imageset │ │ ├── Contents.json │ │ └── silo.jpg │ └── succession.imageset │ │ ├── Contents.json │ │ └── succession.jpeg └── tabColors │ ├── Contents.json │ ├── lightBlue.colorset │ └── Contents.json │ ├── lightPurple.colorset │ └── Contents.json │ └── lightRed.colorset │ └── Contents.json ├── ContentView.swift ├── Preview Content └── Preview Assets.xcassets │ └── Contents.json ├── alertmodal ├── AlertEnvironment.swift ├── AlertManager.swift ├── AlertModal.swift ├── AlertModalView.swift ├── AlertModalWrapper.swift └── ModalContentView.swift ├── animatedbackground ├── AnimatedBackgroundView.swift ├── ToggleAnimationButton.swift └── Utils.swift ├── circularprogress ├── AnimationModel.swift ├── BoltView.swift ├── CircularProgress.swift ├── CircularProgressView.swift └── LockScreenView.swift ├── commons └── PrimaryButton.swift ├── gradientblur ├── DetailsButton.swift ├── GradientBlurView.swift ├── Model.swift ├── MovieCardView.swift ├── MovieDetailsView.swift └── ProfileView.swift ├── horizontalslider ├── HorizontalSlider.swift ├── LowerIndicatorsView.swift ├── SliderView.swift └── TargetIndicatorView.swift ├── imagevariableblur ├── ImageUtils.swift └── ImageVariableBlurView.swift ├── longpressbutton └── LongPressButtonView.swift ├── meshgradientbutton └── MeshGradientButtonView.swift ├── otherstuffs └── VelocityHorizontalScroll.swift ├── revealingbutton ├── ButtonCircularProgressView.swift ├── ButtonsView.swift ├── RevealingButtonModifier.swift └── RevealingButtonView.swift ├── scrollingstackview └── ScollingStackView.swift ├── simplepicker ├── PickerButtonView.swift ├── SimplePickerView.swift ├── TextContentModel.swift └── TextContentView.swift ├── swiftystuffApp.swift ├── tabbar ├── TabBar.swift ├── TabBarView.swift ├── TabButtonLabelsView.swift ├── TabButtonStyle.swift ├── TabItemModel.swift ├── TabScrollContentView.swift └── Tabs.swift └── verticalscrollview ├── VerticalScrollingView.swift ├── WordDetailsView.swift └── WordModel.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swifty Stuff 2 | 3 | ### Collection of all the cool stuff I implemented with Swift UI. 4 | 5 | 6 | **Note: Non of these components were tested for production use, this is just for a demo (UI/UX concepts)** 7 | 8 | [Simple Picker](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/simplepicker) 9 | ![Simple Picker GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/simple_picker.gif?raw=true). 10 | 11 | [Long Press Button](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/longpressbutton) 12 | ![Long Press Button GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/long_press_button.gif?raw=true). 13 | 14 | [Mesh Gradient Button](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/meshgradientbutton) 15 | ![Mesh Gradient Button GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/mesh_gradient_button.gif?raw=true). 16 | 17 | [Revealing Button](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/revealingbutton) 18 | ![Revealing Button GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/revealing_button.gif?raw=true). 19 | 20 | [Horizontal Slider](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/horizontalslider) 21 | ![Horizontal Slider GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/horizontal_slider.gif?raw=true). 22 | 23 | [Scrolling Stack](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/scrollingstackview) 24 | ![Scrolling Stack GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/scrolling_stack.gif?raw=true). 25 | 26 | [Magsafe Circular Progress](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/circularprogress) 27 | ![Magsafe Circular Progress GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/circular_progress.gif?raw=true). 28 | 29 | [Animated Background](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/animatedbackground) 30 | ![Animated Backgound GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/animated_background.gif?raw=true). 31 | 32 | [Custom Tab Bar](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/tabbar) 33 | ![Custom Tab Bar GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/tab_bar.gif?raw=true). 34 | 35 | [Movies Gradient Blur](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/gradientblur) 36 | ![Movies gradient blur demo GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/movies_gradient_blur.gif?raw=true). 37 | 38 | [Alert Modal](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/alertmodal) 39 | ![Alert modal demo GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/alert_modal.gif?raw=true). 40 | 41 | [Vertical Scroll View](https://github.com/abdulrahimiliasu/swiftystuff/tree/main/swiftystuff/verticalscrollview) 42 | ![Vertical scroll demo GIF](https://github.com/abdulrahimiliasu/swiftystuff/blob/main/demo/vertical_scroll.gif?raw=true). 43 | -------------------------------------------------------------------------------- /demo/alert_modal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/alert_modal.gif -------------------------------------------------------------------------------- /demo/animated_background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/animated_background.gif -------------------------------------------------------------------------------- /demo/circular_progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/circular_progress.gif -------------------------------------------------------------------------------- /demo/horizontal_slider.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/horizontal_slider.gif -------------------------------------------------------------------------------- /demo/long_press_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/long_press_button.gif -------------------------------------------------------------------------------- /demo/mesh_gradient_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/mesh_gradient_button.gif -------------------------------------------------------------------------------- /demo/movies_gradient_blur.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/movies_gradient_blur.gif -------------------------------------------------------------------------------- /demo/revealing_button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/revealing_button.gif -------------------------------------------------------------------------------- /demo/scrolling_stack.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/scrolling_stack.gif -------------------------------------------------------------------------------- /demo/simple_picker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/simple_picker.gif -------------------------------------------------------------------------------- /demo/tab_bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/tab_bar.gif -------------------------------------------------------------------------------- /demo/vertical_scroll.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/demo/vertical_scroll.gif -------------------------------------------------------------------------------- /swiftystuff.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4803766A2BD3FE390051ABA8 /* VerticalScrollingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 480376692BD3FE390051ABA8 /* VerticalScrollingView.swift */; }; 11 | 4803766C2BD4001E0051ABA8 /* WordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803766B2BD4001E0051ABA8 /* WordModel.swift */; }; 12 | 4803766E2BD401BD0051ABA8 /* WordDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803766D2BD401BD0051ABA8 /* WordDetailsView.swift */; }; 13 | 480376722BD4079F0051ABA8 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 480376712BD4079F0051ABA8 /* AlertManager.swift */; }; 14 | 480376742BD40B070051ABA8 /* AlertModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 480376732BD40B070051ABA8 /* AlertModalView.swift */; }; 15 | 480376762BD40C520051ABA8 /* ModalContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 480376752BD40C520051ABA8 /* ModalContentView.swift */; }; 16 | 4803767A2BD441570051ABA8 /* AlertModalWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 480376792BD441570051ABA8 /* AlertModalWrapper.swift */; }; 17 | 4803767C2BD47C700051ABA8 /* AlertModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803767B2BD47C700051ABA8 /* AlertModal.swift */; }; 18 | 480376802BD5982F0051ABA8 /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803767F2BD5982F0051ABA8 /* TabBarView.swift */; }; 19 | 481100D22BD86A2C00AF45D4 /* movies_gradient_blur.gif in Resources */ = {isa = PBXBuildFile; fileRef = 481100CF2BD86A2C00AF45D4 /* movies_gradient_blur.gif */; }; 20 | 481100D32BD86A2C00AF45D4 /* vertical_scroll.gif in Resources */ = {isa = PBXBuildFile; fileRef = 481100D02BD86A2C00AF45D4 /* vertical_scroll.gif */; }; 21 | 481100D42BD86A2C00AF45D4 /* alert_modal.gif in Resources */ = {isa = PBXBuildFile; fileRef = 481100D12BD86A2C00AF45D4 /* alert_modal.gif */; }; 22 | 481FFBED2C70EA09007F1559 /* AlertEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481FFBEC2C70EA09007F1559 /* AlertEnvironment.swift */; }; 23 | 481FFBEF2C723C02007F1559 /* LowerIndicatorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481FFBEE2C723C02007F1559 /* LowerIndicatorsView.swift */; }; 24 | 481FFBF12C723C43007F1559 /* TargetIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481FFBF02C723C43007F1559 /* TargetIndicatorView.swift */; }; 25 | 481FFBF32C723C9E007F1559 /* SliderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481FFBF22C723C9E007F1559 /* SliderView.swift */; }; 26 | 4821E40A2D3C753A00420DC9 /* PickerButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E4052D3C753A00420DC9 /* PickerButtonView.swift */; }; 27 | 4821E40B2D3C753A00420DC9 /* VelocityHorizontalScroll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E4032D3C753A00420DC9 /* VelocityHorizontalScroll.swift */; }; 28 | 4821E40C2D3C753A00420DC9 /* PrimaryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E3FA2D3C753A00420DC9 /* PrimaryButton.swift */; }; 29 | 4821E40D2D3C753A00420DC9 /* TextContentModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E4072D3C753A00420DC9 /* TextContentModel.swift */; }; 30 | 4821E40E2D3C753A00420DC9 /* LongPressButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E3FF2D3C753A00420DC9 /* LongPressButtonView.swift */; }; 31 | 4821E40F2D3C753A00420DC9 /* SimplePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E4062D3C753A00420DC9 /* SimplePickerView.swift */; }; 32 | 4821E4102D3C753A00420DC9 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E3FC2D3C753A00420DC9 /* ImageUtils.swift */; }; 33 | 4821E4112D3C753A00420DC9 /* MeshGradientButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E4012D3C753A00420DC9 /* MeshGradientButtonView.swift */; }; 34 | 4821E4122D3C753A00420DC9 /* ImageVariableBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E3FD2D3C753A00420DC9 /* ImageVariableBlurView.swift */; }; 35 | 4821E4132D3C753A00420DC9 /* TextContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4821E4082D3C753A00420DC9 /* TextContentView.swift */; }; 36 | 4829EBFB2C282A9B00DF52CE /* ScollingStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4829EBFA2C282A9B00DF52CE /* ScollingStackView.swift */; }; 37 | 4840C43E2C0B33CB000C2D3C /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4840C43D2C0B33CB000C2D3C /* CircularProgressView.swift */; }; 38 | 4840C4402C0CFA45000C2D3C /* LockScreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4840C43F2C0CFA45000C2D3C /* LockScreenView.swift */; }; 39 | 4840C4422C0CFABB000C2D3C /* AnimationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4840C4412C0CFABB000C2D3C /* AnimationModel.swift */; }; 40 | 4840C4462C0D2951000C2D3C /* CircularProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4840C4452C0D2951000C2D3C /* CircularProgress.swift */; }; 41 | 4840C4482C0D2DF2000C2D3C /* BoltView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4840C4472C0D2DF2000C2D3C /* BoltView.swift */; }; 42 | 4840C44A2C0D353B000C2D3C /* circular_progress.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4840C4492C0D353B000C2D3C /* circular_progress.gif */; }; 43 | 485E3C742BDDB21900997A56 /* TabItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485E3C732BDDB21800997A56 /* TabItemModel.swift */; }; 44 | 485E3C762BDDB31C00997A56 /* TabButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485E3C752BDDB31B00997A56 /* TabButtonStyle.swift */; }; 45 | 48697E6C2C8C95650093A14E /* RevealingButtonModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48697E6B2C8C95650093A14E /* RevealingButtonModifier.swift */; }; 46 | 48697E6E2C8C97600093A14E /* ButtonCircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48697E6D2C8C97600093A14E /* ButtonCircularProgressView.swift */; }; 47 | 48697E702C8C9BC40093A14E /* ButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48697E6F2C8C9BC40093A14E /* ButtonsView.swift */; }; 48 | 48C27F982C751C3A00CB672D /* RevealingButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C27F972C751C3A00CB672D /* RevealingButtonView.swift */; }; 49 | 48C29D8B2C037A460004B39C /* ToggleAnimationButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C29D8A2C037A460004B39C /* ToggleAnimationButton.swift */; }; 50 | 48C29D8D2C03B4BF0004B39C /* animated_background.gif in Resources */ = {isa = PBXBuildFile; fileRef = 48C29D8C2C03B4BF0004B39C /* animated_background.gif */; }; 51 | 48C29D8F2C03B58C0004B39C /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C29D8E2C03B58C0004B39C /* Utils.swift */; }; 52 | 48D0A94C2B5DC86800E002FC /* swiftystuffApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A94B2B5DC86800E002FC /* swiftystuffApp.swift */; }; 53 | 48D0A94E2B5DC86800E002FC /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A94D2B5DC86800E002FC /* ContentView.swift */; }; 54 | 48D0A9502B5DC86A00E002FC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 48D0A94F2B5DC86A00E002FC /* Assets.xcassets */; }; 55 | 48D0A9532B5DC86A00E002FC /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 48D0A9522B5DC86A00E002FC /* Preview Assets.xcassets */; }; 56 | 48D0A9772B5DC9F800E002FC /* GradientBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A9762B5DC9F800E002FC /* GradientBlurView.swift */; }; 57 | 48D0A9792B5DCA1800E002FC /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A9782B5DCA1800E002FC /* Model.swift */; }; 58 | 48D0A97B2B5DCAE800E002FC /* MovieCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A97A2B5DCAE800E002FC /* MovieCardView.swift */; }; 59 | 48D0A97D2B5DCBF500E002FC /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A97C2B5DCBF500E002FC /* ProfileView.swift */; }; 60 | 48D0A97F2B5DCC5E00E002FC /* MovieDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A97E2B5DCC5E00E002FC /* MovieDetailsView.swift */; }; 61 | 48D0A9812B5DCD7C00E002FC /* DetailsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D0A9802B5DCD7C00E002FC /* DetailsButton.swift */; }; 62 | 48D186732BE67DB4000A70AD /* TabScrollContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D186722BE67DB4000A70AD /* TabScrollContentView.swift */; }; 63 | 48D186752BE68342000A70AD /* TabButtonLabelsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D186742BE68342000A70AD /* TabButtonLabelsView.swift */; }; 64 | 48D186772BE6B1E4000A70AD /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D186762BE6B1E4000A70AD /* TabBar.swift */; }; 65 | 48D186792BE6B9AD000A70AD /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D186782BE6B9AD000A70AD /* Tabs.swift */; }; 66 | 48D1867B2BE6C02D000A70AD /* tab_bar.gif in Resources */ = {isa = PBXBuildFile; fileRef = 48D1867A2BE6C02D000A70AD /* tab_bar.gif */; }; 67 | 48D1867E2BE7B2A8000A70AD /* AnimatedBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D1867D2BE7B2A8000A70AD /* AnimatedBackgroundView.swift */; }; 68 | 48F84EC12C5E609F00C3D5F7 /* HorizontalSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48F84EC02C5E609F00C3D5F7 /* HorizontalSlider.swift */; }; 69 | /* End PBXBuildFile section */ 70 | 71 | /* Begin PBXFileReference section */ 72 | 480376692BD3FE390051ABA8 /* VerticalScrollingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalScrollingView.swift; sourceTree = ""; }; 73 | 4803766B2BD4001E0051ABA8 /* WordModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordModel.swift; sourceTree = ""; }; 74 | 4803766D2BD401BD0051ABA8 /* WordDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordDetailsView.swift; sourceTree = ""; }; 75 | 480376712BD4079F0051ABA8 /* AlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertManager.swift; sourceTree = ""; }; 76 | 480376732BD40B070051ABA8 /* AlertModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertModalView.swift; sourceTree = ""; }; 77 | 480376752BD40C520051ABA8 /* ModalContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalContentView.swift; sourceTree = ""; }; 78 | 480376792BD441570051ABA8 /* AlertModalWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertModalWrapper.swift; sourceTree = ""; }; 79 | 4803767B2BD47C700051ABA8 /* AlertModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertModal.swift; sourceTree = ""; }; 80 | 4803767F2BD5982F0051ABA8 /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = ""; }; 81 | 481100CF2BD86A2C00AF45D4 /* movies_gradient_blur.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = movies_gradient_blur.gif; sourceTree = ""; }; 82 | 481100D02BD86A2C00AF45D4 /* vertical_scroll.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = vertical_scroll.gif; sourceTree = ""; }; 83 | 481100D12BD86A2C00AF45D4 /* alert_modal.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = alert_modal.gif; sourceTree = ""; }; 84 | 481FFBEC2C70EA09007F1559 /* AlertEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertEnvironment.swift; sourceTree = ""; }; 85 | 481FFBEE2C723C02007F1559 /* LowerIndicatorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LowerIndicatorsView.swift; sourceTree = ""; }; 86 | 481FFBF02C723C43007F1559 /* TargetIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetIndicatorView.swift; sourceTree = ""; }; 87 | 481FFBF22C723C9E007F1559 /* SliderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderView.swift; sourceTree = ""; }; 88 | 4821E3FA2D3C753A00420DC9 /* PrimaryButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryButton.swift; sourceTree = ""; }; 89 | 4821E3FC2D3C753A00420DC9 /* ImageUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageUtils.swift; sourceTree = ""; }; 90 | 4821E3FD2D3C753A00420DC9 /* ImageVariableBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageVariableBlurView.swift; sourceTree = ""; }; 91 | 4821E3FF2D3C753A00420DC9 /* LongPressButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongPressButtonView.swift; sourceTree = ""; }; 92 | 4821E4012D3C753A00420DC9 /* MeshGradientButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshGradientButtonView.swift; sourceTree = ""; }; 93 | 4821E4032D3C753A00420DC9 /* VelocityHorizontalScroll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VelocityHorizontalScroll.swift; sourceTree = ""; }; 94 | 4821E4052D3C753A00420DC9 /* PickerButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickerButtonView.swift; sourceTree = ""; }; 95 | 4821E4062D3C753A00420DC9 /* SimplePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimplePickerView.swift; sourceTree = ""; }; 96 | 4821E4072D3C753A00420DC9 /* TextContentModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextContentModel.swift; sourceTree = ""; }; 97 | 4821E4082D3C753A00420DC9 /* TextContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextContentView.swift; sourceTree = ""; }; 98 | 4829EBFA2C282A9B00DF52CE /* ScollingStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScollingStackView.swift; sourceTree = ""; }; 99 | 4840C43D2C0B33CB000C2D3C /* CircularProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgressView.swift; sourceTree = ""; }; 100 | 4840C43F2C0CFA45000C2D3C /* LockScreenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenView.swift; sourceTree = ""; }; 101 | 4840C4412C0CFABB000C2D3C /* AnimationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationModel.swift; sourceTree = ""; }; 102 | 4840C4452C0D2951000C2D3C /* CircularProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgress.swift; sourceTree = ""; }; 103 | 4840C4472C0D2DF2000C2D3C /* BoltView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoltView.swift; sourceTree = ""; }; 104 | 4840C4492C0D353B000C2D3C /* circular_progress.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = circular_progress.gif; sourceTree = ""; }; 105 | 485E3C732BDDB21800997A56 /* TabItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabItemModel.swift; sourceTree = ""; }; 106 | 485E3C752BDDB31B00997A56 /* TabButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabButtonStyle.swift; sourceTree = ""; }; 107 | 48697E6B2C8C95650093A14E /* RevealingButtonModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevealingButtonModifier.swift; sourceTree = ""; }; 108 | 48697E6D2C8C97600093A14E /* ButtonCircularProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonCircularProgressView.swift; sourceTree = ""; }; 109 | 48697E6F2C8C9BC40093A14E /* ButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonsView.swift; sourceTree = ""; }; 110 | 48C27F972C751C3A00CB672D /* RevealingButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevealingButtonView.swift; sourceTree = ""; }; 111 | 48C29D8A2C037A460004B39C /* ToggleAnimationButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleAnimationButton.swift; sourceTree = ""; }; 112 | 48C29D8C2C03B4BF0004B39C /* animated_background.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = animated_background.gif; sourceTree = ""; }; 113 | 48C29D8E2C03B58C0004B39C /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; 114 | 48D0A9482B5DC86800E002FC /* swiftystuff.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = swiftystuff.app; sourceTree = BUILT_PRODUCTS_DIR; }; 115 | 48D0A94B2B5DC86800E002FC /* swiftystuffApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = swiftystuffApp.swift; sourceTree = ""; }; 116 | 48D0A94D2B5DC86800E002FC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 117 | 48D0A94F2B5DC86A00E002FC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 118 | 48D0A9522B5DC86A00E002FC /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 119 | 48D0A9762B5DC9F800E002FC /* GradientBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientBlurView.swift; sourceTree = ""; }; 120 | 48D0A9782B5DCA1800E002FC /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; 121 | 48D0A97A2B5DCAE800E002FC /* MovieCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieCardView.swift; sourceTree = ""; }; 122 | 48D0A97C2B5DCBF500E002FC /* ProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileView.swift; sourceTree = ""; }; 123 | 48D0A97E2B5DCC5E00E002FC /* MovieDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieDetailsView.swift; sourceTree = ""; }; 124 | 48D0A9802B5DCD7C00E002FC /* DetailsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsButton.swift; sourceTree = ""; }; 125 | 48D0A9822B5DDA2E00E002FC /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 126 | 48D186722BE67DB4000A70AD /* TabScrollContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabScrollContentView.swift; sourceTree = ""; }; 127 | 48D186742BE68342000A70AD /* TabButtonLabelsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabButtonLabelsView.swift; sourceTree = ""; }; 128 | 48D186762BE6B1E4000A70AD /* TabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = ""; }; 129 | 48D186782BE6B9AD000A70AD /* Tabs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = ""; }; 130 | 48D1867A2BE6C02D000A70AD /* tab_bar.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = tab_bar.gif; sourceTree = ""; }; 131 | 48D1867D2BE7B2A8000A70AD /* AnimatedBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedBackgroundView.swift; sourceTree = ""; }; 132 | 48F84EC02C5E609F00C3D5F7 /* HorizontalSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalSlider.swift; sourceTree = ""; }; 133 | /* End PBXFileReference section */ 134 | 135 | /* Begin PBXFrameworksBuildPhase section */ 136 | 48D0A9452B5DC86800E002FC /* Frameworks */ = { 137 | isa = PBXFrameworksBuildPhase; 138 | buildActionMask = 2147483647; 139 | files = ( 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXFrameworksBuildPhase section */ 144 | 145 | /* Begin PBXGroup section */ 146 | 480376662BD3F0020051ABA8 /* tabbar */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 4803767F2BD5982F0051ABA8 /* TabBarView.swift */, 150 | 485E3C732BDDB21800997A56 /* TabItemModel.swift */, 151 | 485E3C752BDDB31B00997A56 /* TabButtonStyle.swift */, 152 | 48D186722BE67DB4000A70AD /* TabScrollContentView.swift */, 153 | 48D186742BE68342000A70AD /* TabButtonLabelsView.swift */, 154 | 48D186762BE6B1E4000A70AD /* TabBar.swift */, 155 | 48D186782BE6B9AD000A70AD /* Tabs.swift */, 156 | ); 157 | path = tabbar; 158 | sourceTree = ""; 159 | }; 160 | 480376672BD3F3410051ABA8 /* alertmodal */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 4803767B2BD47C700051ABA8 /* AlertModal.swift */, 164 | 480376712BD4079F0051ABA8 /* AlertManager.swift */, 165 | 480376732BD40B070051ABA8 /* AlertModalView.swift */, 166 | 480376752BD40C520051ABA8 /* ModalContentView.swift */, 167 | 480376792BD441570051ABA8 /* AlertModalWrapper.swift */, 168 | 481FFBEC2C70EA09007F1559 /* AlertEnvironment.swift */, 169 | ); 170 | path = alertmodal; 171 | sourceTree = ""; 172 | }; 173 | 480376682BD3FDEF0051ABA8 /* verticalscrollview */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 480376692BD3FE390051ABA8 /* VerticalScrollingView.swift */, 177 | 4803766B2BD4001E0051ABA8 /* WordModel.swift */, 178 | 4803766D2BD401BD0051ABA8 /* WordDetailsView.swift */, 179 | ); 180 | path = verticalscrollview; 181 | sourceTree = ""; 182 | }; 183 | 481100CE2BD86A1A00AF45D4 /* demo */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 4840C4492C0D353B000C2D3C /* circular_progress.gif */, 187 | 48C29D8C2C03B4BF0004B39C /* animated_background.gif */, 188 | 48D1867A2BE6C02D000A70AD /* tab_bar.gif */, 189 | 481100D12BD86A2C00AF45D4 /* alert_modal.gif */, 190 | 481100CF2BD86A2C00AF45D4 /* movies_gradient_blur.gif */, 191 | 481100D02BD86A2C00AF45D4 /* vertical_scroll.gif */, 192 | ); 193 | path = demo; 194 | sourceTree = ""; 195 | }; 196 | 4821E3FB2D3C753A00420DC9 /* commons */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 4821E3FA2D3C753A00420DC9 /* PrimaryButton.swift */, 200 | ); 201 | path = commons; 202 | sourceTree = ""; 203 | }; 204 | 4821E3FE2D3C753A00420DC9 /* imagevariableblur */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | 4821E3FC2D3C753A00420DC9 /* ImageUtils.swift */, 208 | 4821E3FD2D3C753A00420DC9 /* ImageVariableBlurView.swift */, 209 | ); 210 | path = imagevariableblur; 211 | sourceTree = ""; 212 | }; 213 | 4821E4002D3C753A00420DC9 /* longpressbutton */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 4821E3FF2D3C753A00420DC9 /* LongPressButtonView.swift */, 217 | ); 218 | path = longpressbutton; 219 | sourceTree = ""; 220 | }; 221 | 4821E4022D3C753A00420DC9 /* meshgradientbutton */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | 4821E4012D3C753A00420DC9 /* MeshGradientButtonView.swift */, 225 | ); 226 | path = meshgradientbutton; 227 | sourceTree = ""; 228 | }; 229 | 4821E4042D3C753A00420DC9 /* otherstuffs */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | 4821E4032D3C753A00420DC9 /* VelocityHorizontalScroll.swift */, 233 | ); 234 | path = otherstuffs; 235 | sourceTree = ""; 236 | }; 237 | 4821E4092D3C753A00420DC9 /* simplepicker */ = { 238 | isa = PBXGroup; 239 | children = ( 240 | 4821E4052D3C753A00420DC9 /* PickerButtonView.swift */, 241 | 4821E4062D3C753A00420DC9 /* SimplePickerView.swift */, 242 | 4821E4072D3C753A00420DC9 /* TextContentModel.swift */, 243 | 4821E4082D3C753A00420DC9 /* TextContentView.swift */, 244 | ); 245 | path = simplepicker; 246 | sourceTree = ""; 247 | }; 248 | 4829EBF92C282A8500DF52CE /* scrollingstackview */ = { 249 | isa = PBXGroup; 250 | children = ( 251 | 4829EBFA2C282A9B00DF52CE /* ScollingStackView.swift */, 252 | ); 253 | path = scrollingstackview; 254 | sourceTree = ""; 255 | }; 256 | 4840C43C2C0B33B5000C2D3C /* circularprogress */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | 4840C43D2C0B33CB000C2D3C /* CircularProgressView.swift */, 260 | 4840C43F2C0CFA45000C2D3C /* LockScreenView.swift */, 261 | 4840C4412C0CFABB000C2D3C /* AnimationModel.swift */, 262 | 4840C4452C0D2951000C2D3C /* CircularProgress.swift */, 263 | 4840C4472C0D2DF2000C2D3C /* BoltView.swift */, 264 | ); 265 | path = circularprogress; 266 | sourceTree = ""; 267 | }; 268 | 48C27F962C751C2300CB672D /* revealingbutton */ = { 269 | isa = PBXGroup; 270 | children = ( 271 | 48C27F972C751C3A00CB672D /* RevealingButtonView.swift */, 272 | 48697E6B2C8C95650093A14E /* RevealingButtonModifier.swift */, 273 | 48697E6D2C8C97600093A14E /* ButtonCircularProgressView.swift */, 274 | 48697E6F2C8C9BC40093A14E /* ButtonsView.swift */, 275 | ); 276 | path = revealingbutton; 277 | sourceTree = ""; 278 | }; 279 | 48D0A93F2B5DC86800E002FC = { 280 | isa = PBXGroup; 281 | children = ( 282 | 481100CE2BD86A1A00AF45D4 /* demo */, 283 | 48D0A9822B5DDA2E00E002FC /* README.md */, 284 | 48D0A94A2B5DC86800E002FC /* swiftystuff */, 285 | 48D0A9492B5DC86800E002FC /* Products */, 286 | ); 287 | sourceTree = ""; 288 | }; 289 | 48D0A9492B5DC86800E002FC /* Products */ = { 290 | isa = PBXGroup; 291 | children = ( 292 | 48D0A9482B5DC86800E002FC /* swiftystuff.app */, 293 | ); 294 | name = Products; 295 | sourceTree = ""; 296 | }; 297 | 48D0A94A2B5DC86800E002FC /* swiftystuff */ = { 298 | isa = PBXGroup; 299 | children = ( 300 | 4821E3FB2D3C753A00420DC9 /* commons */, 301 | 4821E3FE2D3C753A00420DC9 /* imagevariableblur */, 302 | 4821E4002D3C753A00420DC9 /* longpressbutton */, 303 | 4821E4022D3C753A00420DC9 /* meshgradientbutton */, 304 | 4821E4042D3C753A00420DC9 /* otherstuffs */, 305 | 4821E4092D3C753A00420DC9 /* simplepicker */, 306 | 48C27F962C751C2300CB672D /* revealingbutton */, 307 | 48F84EBF2C5E608900C3D5F7 /* horizontalslider */, 308 | 4829EBF92C282A8500DF52CE /* scrollingstackview */, 309 | 4840C43C2C0B33B5000C2D3C /* circularprogress */, 310 | 48D1867C2BE7B28F000A70AD /* animatedbackground */, 311 | 480376682BD3FDEF0051ABA8 /* verticalscrollview */, 312 | 480376672BD3F3410051ABA8 /* alertmodal */, 313 | 480376662BD3F0020051ABA8 /* tabbar */, 314 | 48D0A9752B5DC9BF00E002FC /* gradientblur */, 315 | 48D0A94B2B5DC86800E002FC /* swiftystuffApp.swift */, 316 | 48D0A94D2B5DC86800E002FC /* ContentView.swift */, 317 | 48D0A94F2B5DC86A00E002FC /* Assets.xcassets */, 318 | 48D0A9512B5DC86A00E002FC /* Preview Content */, 319 | ); 320 | path = swiftystuff; 321 | sourceTree = ""; 322 | }; 323 | 48D0A9512B5DC86A00E002FC /* Preview Content */ = { 324 | isa = PBXGroup; 325 | children = ( 326 | 48D0A9522B5DC86A00E002FC /* Preview Assets.xcassets */, 327 | ); 328 | path = "Preview Content"; 329 | sourceTree = ""; 330 | }; 331 | 48D0A9752B5DC9BF00E002FC /* gradientblur */ = { 332 | isa = PBXGroup; 333 | children = ( 334 | 48D0A9762B5DC9F800E002FC /* GradientBlurView.swift */, 335 | 48D0A9782B5DCA1800E002FC /* Model.swift */, 336 | 48D0A97A2B5DCAE800E002FC /* MovieCardView.swift */, 337 | 48D0A97C2B5DCBF500E002FC /* ProfileView.swift */, 338 | 48D0A97E2B5DCC5E00E002FC /* MovieDetailsView.swift */, 339 | 48D0A9802B5DCD7C00E002FC /* DetailsButton.swift */, 340 | ); 341 | path = gradientblur; 342 | sourceTree = ""; 343 | }; 344 | 48D1867C2BE7B28F000A70AD /* animatedbackground */ = { 345 | isa = PBXGroup; 346 | children = ( 347 | 48D1867D2BE7B2A8000A70AD /* AnimatedBackgroundView.swift */, 348 | 48C29D8A2C037A460004B39C /* ToggleAnimationButton.swift */, 349 | 48C29D8E2C03B58C0004B39C /* Utils.swift */, 350 | ); 351 | path = animatedbackground; 352 | sourceTree = ""; 353 | }; 354 | 48F84EBF2C5E608900C3D5F7 /* horizontalslider */ = { 355 | isa = PBXGroup; 356 | children = ( 357 | 48F84EC02C5E609F00C3D5F7 /* HorizontalSlider.swift */, 358 | 481FFBEE2C723C02007F1559 /* LowerIndicatorsView.swift */, 359 | 481FFBF02C723C43007F1559 /* TargetIndicatorView.swift */, 360 | 481FFBF22C723C9E007F1559 /* SliderView.swift */, 361 | ); 362 | path = horizontalslider; 363 | sourceTree = ""; 364 | }; 365 | /* End PBXGroup section */ 366 | 367 | /* Begin PBXNativeTarget section */ 368 | 48D0A9472B5DC86800E002FC /* swiftystuff */ = { 369 | isa = PBXNativeTarget; 370 | buildConfigurationList = 48D0A96C2B5DC86A00E002FC /* Build configuration list for PBXNativeTarget "swiftystuff" */; 371 | buildPhases = ( 372 | 48D0A9442B5DC86800E002FC /* Sources */, 373 | 48D0A9452B5DC86800E002FC /* Frameworks */, 374 | 48D0A9462B5DC86800E002FC /* Resources */, 375 | ); 376 | buildRules = ( 377 | ); 378 | dependencies = ( 379 | ); 380 | name = swiftystuff; 381 | productName = swiftystuff; 382 | productReference = 48D0A9482B5DC86800E002FC /* swiftystuff.app */; 383 | productType = "com.apple.product-type.application"; 384 | }; 385 | /* End PBXNativeTarget section */ 386 | 387 | /* Begin PBXProject section */ 388 | 48D0A9402B5DC86800E002FC /* Project object */ = { 389 | isa = PBXProject; 390 | attributes = { 391 | BuildIndependentTargetsInParallel = 1; 392 | LastSwiftUpdateCheck = 1500; 393 | LastUpgradeCheck = 1500; 394 | TargetAttributes = { 395 | 48D0A9472B5DC86800E002FC = { 396 | CreatedOnToolsVersion = 15.0; 397 | }; 398 | }; 399 | }; 400 | buildConfigurationList = 48D0A9432B5DC86800E002FC /* Build configuration list for PBXProject "swiftystuff" */; 401 | compatibilityVersion = "Xcode 14.0"; 402 | developmentRegion = en; 403 | hasScannedForEncodings = 0; 404 | knownRegions = ( 405 | en, 406 | Base, 407 | ); 408 | mainGroup = 48D0A93F2B5DC86800E002FC; 409 | productRefGroup = 48D0A9492B5DC86800E002FC /* Products */; 410 | projectDirPath = ""; 411 | projectRoot = ""; 412 | targets = ( 413 | 48D0A9472B5DC86800E002FC /* swiftystuff */, 414 | ); 415 | }; 416 | /* End PBXProject section */ 417 | 418 | /* Begin PBXResourcesBuildPhase section */ 419 | 48D0A9462B5DC86800E002FC /* Resources */ = { 420 | isa = PBXResourcesBuildPhase; 421 | buildActionMask = 2147483647; 422 | files = ( 423 | 481100D22BD86A2C00AF45D4 /* movies_gradient_blur.gif in Resources */, 424 | 48D0A9532B5DC86A00E002FC /* Preview Assets.xcassets in Resources */, 425 | 4840C44A2C0D353B000C2D3C /* circular_progress.gif in Resources */, 426 | 48D1867B2BE6C02D000A70AD /* tab_bar.gif in Resources */, 427 | 48D0A9502B5DC86A00E002FC /* Assets.xcassets in Resources */, 428 | 481100D32BD86A2C00AF45D4 /* vertical_scroll.gif in Resources */, 429 | 48C29D8D2C03B4BF0004B39C /* animated_background.gif in Resources */, 430 | 481100D42BD86A2C00AF45D4 /* alert_modal.gif in Resources */, 431 | ); 432 | runOnlyForDeploymentPostprocessing = 0; 433 | }; 434 | /* End PBXResourcesBuildPhase section */ 435 | 436 | /* Begin PBXSourcesBuildPhase section */ 437 | 48D0A9442B5DC86800E002FC /* Sources */ = { 438 | isa = PBXSourcesBuildPhase; 439 | buildActionMask = 2147483647; 440 | files = ( 441 | 480376802BD5982F0051ABA8 /* TabBarView.swift in Sources */, 442 | 4821E40A2D3C753A00420DC9 /* PickerButtonView.swift in Sources */, 443 | 4821E40B2D3C753A00420DC9 /* VelocityHorizontalScroll.swift in Sources */, 444 | 4821E40C2D3C753A00420DC9 /* PrimaryButton.swift in Sources */, 445 | 4821E40D2D3C753A00420DC9 /* TextContentModel.swift in Sources */, 446 | 4821E40E2D3C753A00420DC9 /* LongPressButtonView.swift in Sources */, 447 | 4821E40F2D3C753A00420DC9 /* SimplePickerView.swift in Sources */, 448 | 4821E4102D3C753A00420DC9 /* ImageUtils.swift in Sources */, 449 | 4821E4112D3C753A00420DC9 /* MeshGradientButtonView.swift in Sources */, 450 | 4821E4122D3C753A00420DC9 /* ImageVariableBlurView.swift in Sources */, 451 | 4821E4132D3C753A00420DC9 /* TextContentView.swift in Sources */, 452 | 4840C43E2C0B33CB000C2D3C /* CircularProgressView.swift in Sources */, 453 | 4803766E2BD401BD0051ABA8 /* WordDetailsView.swift in Sources */, 454 | 4840C4402C0CFA45000C2D3C /* LockScreenView.swift in Sources */, 455 | 480376762BD40C520051ABA8 /* ModalContentView.swift in Sources */, 456 | 48D186752BE68342000A70AD /* TabButtonLabelsView.swift in Sources */, 457 | 4840C4422C0CFABB000C2D3C /* AnimationModel.swift in Sources */, 458 | 48D0A94E2B5DC86800E002FC /* ContentView.swift in Sources */, 459 | 48C29D8F2C03B58C0004B39C /* Utils.swift in Sources */, 460 | 48D0A97F2B5DCC5E00E002FC /* MovieDetailsView.swift in Sources */, 461 | 48D186772BE6B1E4000A70AD /* TabBar.swift in Sources */, 462 | 48697E6C2C8C95650093A14E /* RevealingButtonModifier.swift in Sources */, 463 | 4840C4482C0D2DF2000C2D3C /* BoltView.swift in Sources */, 464 | 4803766A2BD3FE390051ABA8 /* VerticalScrollingView.swift in Sources */, 465 | 485E3C762BDDB31C00997A56 /* TabButtonStyle.swift in Sources */, 466 | 480376722BD4079F0051ABA8 /* AlertManager.swift in Sources */, 467 | 48D0A97B2B5DCAE800E002FC /* MovieCardView.swift in Sources */, 468 | 481FFBEF2C723C02007F1559 /* LowerIndicatorsView.swift in Sources */, 469 | 480376742BD40B070051ABA8 /* AlertModalView.swift in Sources */, 470 | 48C29D8B2C037A460004B39C /* ToggleAnimationButton.swift in Sources */, 471 | 481FFBF12C723C43007F1559 /* TargetIndicatorView.swift in Sources */, 472 | 48C27F982C751C3A00CB672D /* RevealingButtonView.swift in Sources */, 473 | 48D0A9772B5DC9F800E002FC /* GradientBlurView.swift in Sources */, 474 | 4803767C2BD47C700051ABA8 /* AlertModal.swift in Sources */, 475 | 48697E6E2C8C97600093A14E /* ButtonCircularProgressView.swift in Sources */, 476 | 48D0A94C2B5DC86800E002FC /* swiftystuffApp.swift in Sources */, 477 | 48D186732BE67DB4000A70AD /* TabScrollContentView.swift in Sources */, 478 | 48D0A9812B5DCD7C00E002FC /* DetailsButton.swift in Sources */, 479 | 48F84EC12C5E609F00C3D5F7 /* HorizontalSlider.swift in Sources */, 480 | 48697E702C8C9BC40093A14E /* ButtonsView.swift in Sources */, 481 | 4803767A2BD441570051ABA8 /* AlertModalWrapper.swift in Sources */, 482 | 485E3C742BDDB21900997A56 /* TabItemModel.swift in Sources */, 483 | 48D0A97D2B5DCBF500E002FC /* ProfileView.swift in Sources */, 484 | 4840C4462C0D2951000C2D3C /* CircularProgress.swift in Sources */, 485 | 481FFBF32C723C9E007F1559 /* SliderView.swift in Sources */, 486 | 48D0A9792B5DCA1800E002FC /* Model.swift in Sources */, 487 | 48D1867E2BE7B2A8000A70AD /* AnimatedBackgroundView.swift in Sources */, 488 | 48D186792BE6B9AD000A70AD /* Tabs.swift in Sources */, 489 | 4829EBFB2C282A9B00DF52CE /* ScollingStackView.swift in Sources */, 490 | 481FFBED2C70EA09007F1559 /* AlertEnvironment.swift in Sources */, 491 | 4803766C2BD4001E0051ABA8 /* WordModel.swift in Sources */, 492 | ); 493 | runOnlyForDeploymentPostprocessing = 0; 494 | }; 495 | /* End PBXSourcesBuildPhase section */ 496 | 497 | /* Begin XCBuildConfiguration section */ 498 | 48D0A96A2B5DC86A00E002FC /* Debug */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | ALWAYS_SEARCH_USER_PATHS = NO; 502 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 503 | CLANG_ANALYZER_NONNULL = YES; 504 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 505 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 506 | CLANG_ENABLE_MODULES = YES; 507 | CLANG_ENABLE_OBJC_ARC = YES; 508 | CLANG_ENABLE_OBJC_WEAK = YES; 509 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 510 | CLANG_WARN_BOOL_CONVERSION = YES; 511 | CLANG_WARN_COMMA = YES; 512 | CLANG_WARN_CONSTANT_CONVERSION = YES; 513 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 514 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 515 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 516 | CLANG_WARN_EMPTY_BODY = YES; 517 | CLANG_WARN_ENUM_CONVERSION = YES; 518 | CLANG_WARN_INFINITE_RECURSION = YES; 519 | CLANG_WARN_INT_CONVERSION = YES; 520 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 521 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 522 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 523 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 524 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 525 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 526 | CLANG_WARN_STRICT_PROTOTYPES = YES; 527 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 528 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 529 | CLANG_WARN_UNREACHABLE_CODE = YES; 530 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 531 | COPY_PHASE_STRIP = NO; 532 | DEBUG_INFORMATION_FORMAT = dwarf; 533 | ENABLE_STRICT_OBJC_MSGSEND = YES; 534 | ENABLE_TESTABILITY = YES; 535 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 536 | GCC_C_LANGUAGE_STANDARD = gnu17; 537 | GCC_DYNAMIC_NO_PIC = NO; 538 | GCC_NO_COMMON_BLOCKS = YES; 539 | GCC_OPTIMIZATION_LEVEL = 0; 540 | GCC_PREPROCESSOR_DEFINITIONS = ( 541 | "DEBUG=1", 542 | "$(inherited)", 543 | ); 544 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 545 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 546 | GCC_WARN_UNDECLARED_SELECTOR = YES; 547 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 548 | GCC_WARN_UNUSED_FUNCTION = YES; 549 | GCC_WARN_UNUSED_VARIABLE = YES; 550 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 551 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 552 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 553 | MTL_FAST_MATH = YES; 554 | ONLY_ACTIVE_ARCH = YES; 555 | SDKROOT = iphoneos; 556 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 557 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 558 | }; 559 | name = Debug; 560 | }; 561 | 48D0A96B2B5DC86A00E002FC /* Release */ = { 562 | isa = XCBuildConfiguration; 563 | buildSettings = { 564 | ALWAYS_SEARCH_USER_PATHS = NO; 565 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 566 | CLANG_ANALYZER_NONNULL = YES; 567 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 568 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 569 | CLANG_ENABLE_MODULES = YES; 570 | CLANG_ENABLE_OBJC_ARC = YES; 571 | CLANG_ENABLE_OBJC_WEAK = YES; 572 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 573 | CLANG_WARN_BOOL_CONVERSION = YES; 574 | CLANG_WARN_COMMA = YES; 575 | CLANG_WARN_CONSTANT_CONVERSION = YES; 576 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 577 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 578 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 579 | CLANG_WARN_EMPTY_BODY = YES; 580 | CLANG_WARN_ENUM_CONVERSION = YES; 581 | CLANG_WARN_INFINITE_RECURSION = YES; 582 | CLANG_WARN_INT_CONVERSION = YES; 583 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 584 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 585 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 586 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 587 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 588 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 589 | CLANG_WARN_STRICT_PROTOTYPES = YES; 590 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 591 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 592 | CLANG_WARN_UNREACHABLE_CODE = YES; 593 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 594 | COPY_PHASE_STRIP = NO; 595 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 596 | ENABLE_NS_ASSERTIONS = NO; 597 | ENABLE_STRICT_OBJC_MSGSEND = YES; 598 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 599 | GCC_C_LANGUAGE_STANDARD = gnu17; 600 | GCC_NO_COMMON_BLOCKS = YES; 601 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 602 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 603 | GCC_WARN_UNDECLARED_SELECTOR = YES; 604 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 605 | GCC_WARN_UNUSED_FUNCTION = YES; 606 | GCC_WARN_UNUSED_VARIABLE = YES; 607 | IPHONEOS_DEPLOYMENT_TARGET = 17.0; 608 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 609 | MTL_ENABLE_DEBUG_INFO = NO; 610 | MTL_FAST_MATH = YES; 611 | SDKROOT = iphoneos; 612 | SWIFT_COMPILATION_MODE = wholemodule; 613 | VALIDATE_PRODUCT = YES; 614 | }; 615 | name = Release; 616 | }; 617 | 48D0A96D2B5DC86A00E002FC /* Debug */ = { 618 | isa = XCBuildConfiguration; 619 | buildSettings = { 620 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 621 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 622 | CODE_SIGN_STYLE = Automatic; 623 | CURRENT_PROJECT_VERSION = 1; 624 | DEVELOPMENT_ASSET_PATHS = "\"swiftystuff/Preview Content\""; 625 | DEVELOPMENT_TEAM = ""; 626 | ENABLE_PREVIEWS = YES; 627 | GENERATE_INFOPLIST_FILE = YES; 628 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 629 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 630 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 631 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 632 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 633 | LD_RUNPATH_SEARCH_PATHS = ( 634 | "$(inherited)", 635 | "@executable_path/Frameworks", 636 | ); 637 | MARKETING_VERSION = 1.0; 638 | PRODUCT_BUNDLE_IDENTIFIER = com.pentagonlabs.swiftystuff; 639 | PRODUCT_NAME = "$(TARGET_NAME)"; 640 | SWIFT_EMIT_LOC_STRINGS = YES; 641 | SWIFT_VERSION = 5.0; 642 | TARGETED_DEVICE_FAMILY = "1,2"; 643 | }; 644 | name = Debug; 645 | }; 646 | 48D0A96E2B5DC86A00E002FC /* Release */ = { 647 | isa = XCBuildConfiguration; 648 | buildSettings = { 649 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 650 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 651 | CODE_SIGN_STYLE = Automatic; 652 | CURRENT_PROJECT_VERSION = 1; 653 | DEVELOPMENT_ASSET_PATHS = "\"swiftystuff/Preview Content\""; 654 | DEVELOPMENT_TEAM = ""; 655 | ENABLE_PREVIEWS = YES; 656 | GENERATE_INFOPLIST_FILE = YES; 657 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 658 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 659 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 660 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 661 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 662 | LD_RUNPATH_SEARCH_PATHS = ( 663 | "$(inherited)", 664 | "@executable_path/Frameworks", 665 | ); 666 | MARKETING_VERSION = 1.0; 667 | PRODUCT_BUNDLE_IDENTIFIER = com.pentagonlabs.swiftystuff; 668 | PRODUCT_NAME = "$(TARGET_NAME)"; 669 | SWIFT_EMIT_LOC_STRINGS = YES; 670 | SWIFT_VERSION = 5.0; 671 | TARGETED_DEVICE_FAMILY = "1,2"; 672 | }; 673 | name = Release; 674 | }; 675 | /* End XCBuildConfiguration section */ 676 | 677 | /* Begin XCConfigurationList section */ 678 | 48D0A9432B5DC86800E002FC /* Build configuration list for PBXProject "swiftystuff" */ = { 679 | isa = XCConfigurationList; 680 | buildConfigurations = ( 681 | 48D0A96A2B5DC86A00E002FC /* Debug */, 682 | 48D0A96B2B5DC86A00E002FC /* Release */, 683 | ); 684 | defaultConfigurationIsVisible = 0; 685 | defaultConfigurationName = Release; 686 | }; 687 | 48D0A96C2B5DC86A00E002FC /* Build configuration list for PBXNativeTarget "swiftystuff" */ = { 688 | isa = XCConfigurationList; 689 | buildConfigurations = ( 690 | 48D0A96D2B5DC86A00E002FC /* Debug */, 691 | 48D0A96E2B5DC86A00E002FC /* Release */, 692 | ); 693 | defaultConfigurationIsVisible = 0; 694 | defaultConfigurationName = Release; 695 | }; 696 | /* End XCConfigurationList section */ 697 | }; 698 | rootObject = 48D0A9402B5DC86800E002FC /* Project object */; 699 | } 700 | -------------------------------------------------------------------------------- /swiftystuff.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /swiftystuff.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /swiftystuff.xcodeproj/project.xcworkspace/xcuserdata/aillo.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/swiftystuff.xcodeproj/project.xcworkspace/xcuserdata/aillo.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /swiftystuff.xcodeproj/xcuserdata/aillo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /swiftystuff.xcodeproj/xcuserdata/aillo.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | swiftystuff.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | swiftystuffUITests copy 2.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 2 16 | 17 | swiftystuffUITests copy.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "systemBlueColor" 7 | }, 8 | "idiom" : "universal" 9 | } 10 | ], 11 | "info" : { 12 | "author" : "xcode", 13 | "version" : 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Logo.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/AppIcon.appiconset/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/swiftystuff/Assets.xcassets/AppIcon.appiconset/Logo.png -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/bgColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xFF", 9 | "green" : "0xFF", 10 | "red" : "0xFF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "platform" : "ios", 24 | "reference" : "secondarySystemBackgroundColor" 25 | }, 26 | "idiom" : "universal" 27 | } 28 | ], 29 | "info" : { 30 | "author" : "xcode", 31 | "version" : 1 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/chernobyl.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "chernobyl.jpg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/chernobyl.imageset/chernobyl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/swiftystuff/Assets.xcassets/movies/chernobyl.imageset/chernobyl.jpg -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/silo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "silo.jpg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/silo.imageset/silo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/swiftystuff/Assets.xcassets/movies/silo.imageset/silo.jpg -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/succession.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "succession.jpeg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/movies/succession.imageset/succession.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdulrahimiliasu/swiftystuff/e056b57f96345b5bf877f6b67d9124e570770a44/swiftystuff/Assets.xcassets/movies/succession.imageset/succession.jpeg -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/tabColors/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/tabColors/lightBlue.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xFC", 9 | "green" : "0xE5", 10 | "red" : "0xB3" 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" : "0xFC", 27 | "green" : "0xE5", 28 | "red" : "0xB3" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/tabColors/lightPurple.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xE9", 9 | "green" : "0xC4", 10 | "red" : "0xD1" 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" : "0xE9", 27 | "green" : "0xC4", 28 | "red" : "0xD1" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /swiftystuff/Assets.xcassets/tabColors/lightRed.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xD2", 9 | "green" : "0xCD", 10 | "red" : "0xFF" 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" : "0xD2", 27 | "green" : "0xCD", 28 | "red" : "0xFF" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /swiftystuff/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | NavigationView { 13 | VStack { 14 | NavigationLink("Simple Picker View") { 15 | SimplePickerView() 16 | } 17 | NavigationLink("Long Press Button View") { 18 | LongPressButtonView() 19 | } 20 | NavigationLink("Image Variable Blur View") { 21 | ImageVariableBlurView(imageName: "silo", blurRadius: 20, position: .bottom) 22 | } 23 | NavigationLink("Mesh Gradient Button") { 24 | if #available(iOS 18.0, *) { 25 | MeshGradientButtonView() 26 | } else { 27 | Text("This view is only available in iOS 18 and newer") 28 | } 29 | } 30 | NavigationLink("Progressive Blur") { 31 | GradientBlurView() 32 | } 33 | NavigationLink("Alert Modal") { 34 | AlertModalView() 35 | } 36 | NavigationLink("Vertical Scroll View") { 37 | VerticalScrollingView() 38 | } 39 | NavigationLink("TabBar View") { 40 | TabBarView() 41 | } 42 | NavigationLink("Animated Background View") { 43 | AnimatedBackgroundView() 44 | } 45 | NavigationLink("Circular Progress View") { 46 | CircularProgressView() 47 | } 48 | } 49 | .navigationTitle("Swifty Stuff") 50 | .navigationBarTitleDisplayMode(.inline) 51 | } 52 | } 53 | } 54 | 55 | #Preview { 56 | ContentView() 57 | } 58 | -------------------------------------------------------------------------------- /swiftystuff/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /swiftystuff/alertmodal/AlertEnvironment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlertEnvironment.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 17/08/2024. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct AlertModalKey: EnvironmentKey { 12 | static var defaultValue: AlertManager = AlertManager { _ in } hide: {} 13 | } 14 | 15 | extension EnvironmentValues { 16 | var alertModal: AlertManager { 17 | get { self[AlertModalKey.self] } 18 | set { self[AlertModalKey.self] = newValue } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /swiftystuff/alertmodal/AlertManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlertViewModel.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import Combine 9 | import Foundation 10 | 11 | typealias ShowAlert = (_ modal: AlertModalType) -> Void 12 | typealias HideAlert = () -> Void 13 | 14 | struct AlertManager { 15 | let show: ShowAlert 16 | let hide: HideAlert 17 | } 18 | -------------------------------------------------------------------------------- /swiftystuff/alertmodal/AlertModal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Model.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/04/2024. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct AlertModal: Identifiable { 12 | let id = UUID() 13 | let color: Color 14 | let heading: String 15 | let subHeading: String 16 | let icon: String 17 | } 18 | 19 | enum AlertModalType: Identifiable, Hashable { 20 | case success, error, warning, info, custom(color: Color, heading: String, subHeading: String, icon: String) 21 | 22 | var id: Self { self } 23 | 24 | var value: AlertModal { 25 | switch self { 26 | case .success: 27 | return .init(color: .green, heading: "Success", subHeading: "Be aware, something happened!", icon: "checkmark.circle.fill") 28 | case .error: 29 | return .init(color: .red, heading: "Error", subHeading: "Be aware, something happened!", icon: "xmark.circle.fill") 30 | case .warning: 31 | return .init(color: .orange, heading: "Warning", subHeading: "Be aware, something happened!", icon: "exclamationmark.triangle.fill") 32 | case .info: 33 | return .init(color: .blue, heading: "Info", subHeading: "Be aware, something happened!", icon: "info.circle.fill") 34 | case .custom(color: let color, heading: let heading, subHeading: let subHeading, icon: let icon): 35 | return .init(color: color, heading: heading, subHeading: subHeading, icon: icon) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /swiftystuff/alertmodal/AlertModalView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlertModalView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ShowModalView: View { 11 | @Environment(\.alertModal) var alertModal: AlertManager 12 | 13 | var body: some View { 14 | NavigationStack { 15 | VStack(spacing: 50) { 16 | HStack { 17 | Button { alertModal.show(.success) } label: { Text("Success") }.tint(.green) 18 | Button { alertModal.show(.error) } label: { Text("Error") }.tint(.red) 19 | Button { alertModal.show(.warning) } label: { Text("Warning") }.tint(.orange) 20 | Button { alertModal.show(.info) } label: { Text("Info") }.tint(.blue) 21 | } 22 | .buttonStyle(.bordered) 23 | 24 | NavigationLink("Navigate") { 25 | Button { 26 | alertModal.show(.custom(color: .purple, heading: "Custom", subHeading: "try some custom stuff!", icon: "circle")) 27 | } label: { Text("Custom") }.tint(.purple) 28 | } 29 | } 30 | 31 | .padding() 32 | } 33 | } 34 | } 35 | 36 | // @main entry point 37 | struct AlertModalView: View { 38 | var body: some View { 39 | WithAlertModal { 40 | ShowModalView() 41 | } 42 | } 43 | } 44 | 45 | #Preview { 46 | AlertModalView() 47 | } 48 | -------------------------------------------------------------------------------- /swiftystuff/alertmodal/AlertModalWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlertModalWrapper.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WithAlertModal: View where Content: View { 11 | @ViewBuilder var content: () -> Content 12 | @State private var alertModal: AlertModalType? 13 | 14 | var body: some View { 15 | ZStack { 16 | content() 17 | } 18 | .sheet(item: $alertModal) { modal in ModalContentView(modal: modal) } 19 | .environment(\.alertModal, AlertManager(show: { modal in 20 | alertModal = modal 21 | }, hide: { 22 | alertModal = nil 23 | })) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /swiftystuff/alertmodal/ModalContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ModalContentView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct AlertDurationIndicator: View { 11 | let duration: TimeInterval 12 | 13 | var body: some View { 14 | ZStack(alignment: .leading) { 15 | RoundedRectangle(cornerRadius: 30, style: .continuous) 16 | .fill(Color.gray.opacity(0.2)) 17 | .frame(width: 50, height: 5) 18 | RoundedRectangle(cornerRadius: 30, style: .continuous) 19 | .fill(Color.gray.opacity(0.4)) 20 | .frame(height: 5) 21 | .keyframeAnimator(initialValue: 0, repeating: true) { content, value in 22 | content 23 | .frame(width: value) 24 | } keyframes: { _ in 25 | KeyframeTrack { 26 | LinearKeyframe(10, duration: duration) 27 | LinearKeyframe(20, duration: duration) 28 | LinearKeyframe(30, duration: duration) 29 | LinearKeyframe(40, duration: duration) 30 | LinearKeyframe(50, duration: duration) 31 | } 32 | } 33 | } 34 | } 35 | } 36 | 37 | struct AlertBody: View { 38 | @Environment(\.alertModal) var alertModal: AlertManager 39 | 40 | let modal: AlertModal 41 | let duration: TimeInterval 42 | 43 | var body: some View { 44 | VStack(spacing: 20) { 45 | AlertDurationIndicator(duration: duration) 46 | .padding(.bottom, 25) 47 | Image(systemName: modal.icon) 48 | .font(.system(size: 70)) 49 | .foregroundStyle(modal.color) 50 | .symbolRenderingMode(.hierarchical) 51 | .symbolEffect(.pulse) 52 | VStack(spacing: 10) { 53 | Text(modal.heading) 54 | .font(.title2) 55 | .bold() 56 | Text(modal.subHeading) 57 | .font(.caption) 58 | .foregroundStyle(.secondary) 59 | } 60 | // TODO: Add onAction Button 61 | } 62 | .interactiveDismissDisabled(true) 63 | .onAppear(perform: { 64 | DispatchQueue.main.asyncAfter(deadline: .now() + duration * 5) { 65 | alertModal.hide() 66 | } 67 | }) 68 | } 69 | } 70 | 71 | struct ModalContentView: View { 72 | let modal: AlertModalType 73 | 74 | var body: some View { 75 | AlertBody(modal: modal.value, duration: 0.5) 76 | .presentationBackground(.linearGradient(colors: [Color.clear, modal.value.color.opacity(0.2)], startPoint: .top, endPoint: .bottom)) 77 | .presentationDetents([.height(290)]) 78 | .frame(maxWidth: .infinity, maxHeight: .infinity) 79 | .background(Color("bgColor")) 80 | .clipShape(.rect(cornerRadius: 30.0)) 81 | .presentationBackgroundInteraction(.disabled) 82 | .padding() 83 | } 84 | } 85 | 86 | #Preview { 87 | ModalContentView(modal: .info) 88 | } 89 | -------------------------------------------------------------------------------- /swiftystuff/animatedbackground/AnimatedBackgroundView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimatedBackgroundView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 05/05/2024. 6 | // 7 | import SwiftUI 8 | 9 | struct AnimatedBackgroundView: View { 10 | @State private var isShowAnimation = false 11 | var body: some View { 12 | GeometryReader { proxy in 13 | VStack { 14 | VStack(alignment: .leading) { 15 | if isShowAnimation { 16 | ForEach(texts.indices, id: \.self) { index in 17 | Text(texts[index]) 18 | .transition(getIndexTransition(index)) 19 | .opacity(getIndexOpacity(index, size: texts.count)) 20 | } 21 | } 22 | } 23 | .frame(minHeight: 500) 24 | .shadow(color: .black.opacity(0.1), radius: 5, x: 0.0, y: 10) 25 | .font(.system(size: 30, weight: .bold)) 26 | ToggleAnimationButton(isShowAnimation: $isShowAnimation) 27 | } 28 | .frame(width: proxy.size.width, height: proxy.size.height) 29 | .background(AnimatedBackground()) 30 | } 31 | .ignoresSafeArea(edges: .bottom) 32 | } 33 | } 34 | 35 | #Preview { 36 | AnimatedBackgroundView() 37 | } 38 | 39 | /// Animated background based on phases 40 | private struct AnimatedBackground: View { 41 | var body: some View { 42 | VStack { 43 | Rectangle() 44 | .frame(height: 150) 45 | .phaseAnimator(phases, content: { content, phase in 46 | content 47 | .overlay(phase) 48 | .blur(radius: 180.0) 49 | 50 | }, animation: { _ in .easeInOut(duration: 3) }) 51 | Spacer() 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /swiftystuff/animatedbackground/ToggleAnimationButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToggleAnimationButton.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 26/05/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ToggleAnimationButton: View { 11 | @Binding var isShowAnimation: Bool 12 | @State private var symbolEffectValue = false 13 | 14 | func toggleAnimation() { 15 | withAnimation { 16 | isShowAnimation.toggle() 17 | symbolEffectValue.toggle() 18 | } 19 | } 20 | 21 | var body: some View { 22 | Button { toggleAnimation() } label: { 23 | HStack { 24 | Image(systemName: isShowAnimation ? "circle.fill" : "circle") 25 | .symbolEffect(.bounce.down, value: symbolEffectValue) 26 | .foregroundStyle(isShowAnimation ? .green : .primary) 27 | Text("Toggle animation") 28 | } 29 | } 30 | .foregroundStyle(.primary) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /swiftystuff/animatedbackground/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 26/05/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | let texts = ["Really Simple", "Animations", "In Swift UI", "With", "Animated Background", "& Animated Text"] 11 | let phases: [Color] = [.blue, .red, .green, .orange, .yellow, .purple, .mint, .pink] 12 | 13 | /// Calculates and returns the opacity of a view based on it's index in for-each loop 14 | func getIndexOpacity(_ index: Int, size: Int) -> Double { 15 | return Double(1 - Double(index) / Double(size)) * 0.9 16 | } 17 | 18 | /// Calculates and returns the transition delay of a view based on it's index in for-each loop 19 | func getIndexTransition(_ index: Int) -> some Transition { 20 | return .blurReplace(.upUp).animation(.bouncy.delay(Double(index) * 0.3)) 21 | } 22 | -------------------------------------------------------------------------------- /swiftystuff/circularprogress/AnimationModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationValues.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 02/06/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | let initialAnimationValues: AnimationValues = .init(from: 0.0, to: 0.0, lineWidth: 0.0) 11 | let startAnimationValues: AnimationValues = .init(from: 0.0, to: 0.4, lineWidth: 15.0) 12 | let finishAnimationValues: AnimationValues = .init(from: 1.0, to: 2.0, lineWidth: 0.01) 13 | 14 | struct AnimationValues { 15 | var from: CGFloat 16 | var to: CGFloat 17 | var lineWidth: CGFloat 18 | } 19 | 20 | enum AnimationPhase { 21 | case initial, start, finish 22 | 23 | var values: AnimationValues { 24 | switch self { 25 | case .initial: 26 | return initialAnimationValues 27 | case .start: 28 | return startAnimationValues 29 | case .finish: 30 | return finishAnimationValues 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /swiftystuff/circularprogress/BoltView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BoltView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 03/06/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BoltView: View { 11 | @Binding var symbolEffectValue: Bool 12 | var body: some View { 13 | Image(systemName: "bolt.fill") 14 | .symbolEffect(.bounce.down, value: symbolEffectValue) 15 | .font(.system(size: 100)) 16 | .foregroundStyle(.green) 17 | } 18 | } 19 | 20 | #Preview { 21 | BoltView(symbolEffectValue: .constant(false)) 22 | } 23 | -------------------------------------------------------------------------------- /swiftystuff/circularprogress/CircularProgress.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 03/06/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CircularProgressBackground: View { 11 | @Binding var animationPhase: AnimationPhase 12 | var body: some View { 13 | Circle() 14 | .rotation(.degrees(-90)) 15 | .stroke(.tertiary.opacity(0.15), style: .init(lineWidth: 15, lineCap: .round)) 16 | .transition(.blurReplace(.downUp).animation(.bouncy)) 17 | .opacity(animationPhase == .finish || animationPhase == .initial ? 0 : 1) 18 | } 19 | } 20 | 21 | struct CircularProgressIndicator: View { 22 | @Binding var animationPhase: AnimationPhase 23 | var body: some View { 24 | Circle() 25 | .trim(from: animationPhase.values.from, to: animationPhase.values.to) 26 | .rotation(.degrees(-90)) 27 | .stroke(.green, style: .init(lineWidth: animationPhase.values.lineWidth, lineCap: .round)) 28 | .shadow(color: .black.opacity(animationPhase == .finish ? 0 : 0.1), radius: 10, x: 0, y: 5) 29 | .transition(.blurReplace(.upUp).animation(.bouncy)) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /swiftystuff/circularprogress/CircularProgressView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircularProgressView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 01/06/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | private let duration: TimeInterval = 0.6 11 | 12 | struct CircularProgressView: View { 13 | @State private var isShowAnimation = false 14 | @State private var symbolEffectValue = false 15 | @State private var animationPhase: AnimationPhase = .initial 16 | 17 | var body: some View { 18 | ZStack { 19 | LockScreenView() 20 | .blur(radius: isShowAnimation ? 50 : 0) 21 | VStack { 22 | ZStack { 23 | if isShowAnimation { 24 | CircularProgressBackground(animationPhase: $animationPhase) 25 | CircularProgressIndicator(animationPhase: $animationPhase) 26 | .background(BoltView(symbolEffectValue: $symbolEffectValue)) 27 | } 28 | } 29 | .padding(.horizontal, 40) 30 | Spacer() 31 | Button("Toggle animation") { animateCircularProgress() } 32 | .foregroundStyle(.primary) 33 | .phaseAnimator([0, 10], content: { content, phase in 34 | content.offset(y: phase) 35 | }, animation: { _ in .easeInOut.speed(0.5) }) 36 | } 37 | } 38 | } 39 | } 40 | 41 | extension CircularProgressView { 42 | func toggleAnimation() { 43 | animationPhase = .initial 44 | withAnimation { isShowAnimation.toggle() } 45 | } 46 | 47 | /// Set phase to start 48 | func startAnimation() { 49 | toggleAnimation() 50 | withAnimation(.snappy(duration: duration)) { animationPhase = .start } 51 | } 52 | 53 | /// Set phase to finish 54 | func finishAnimation() { 55 | withAnimation(.snappy(duration: duration), completionCriteria: .logicallyComplete) 56 | { animationPhase = .finish } 57 | completion: { toggleAnimation() } 58 | } 59 | 60 | /// Animate based on phase 61 | func animateCircularProgress() { 62 | isShowAnimation ? finishAnimation() : startAnimation() 63 | symbolEffectValue.toggle() 64 | } 65 | } 66 | 67 | #Preview { 68 | CircularProgressView() 69 | } 70 | -------------------------------------------------------------------------------- /swiftystuff/circularprogress/LockScreenView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LockScreenView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 02/06/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct LockScreenView: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | VStack(spacing: 20) { 14 | Image(systemName: "lock.fill") 15 | Text("15:43") 16 | .font(.system(size: 80, design: .rounded)) 17 | Spacer() 18 | } 19 | .frame(width: proxy.size.width, height: proxy.size.height) 20 | } 21 | } 22 | } 23 | 24 | #Preview { 25 | LockScreenView() 26 | } 27 | -------------------------------------------------------------------------------- /swiftystuff/commons/PrimaryButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PrimaryButton.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 2025. 01. 18.. 6 | // 7 | 8 | import SwiftUI 9 | 10 | private struct PrimaryButtonStyle: ButtonStyle { 11 | func makeBody(configuration: Configuration) -> some View { 12 | configuration.label 13 | .scaleEffect(configuration.isPressed ? 0.9 : 1) 14 | .animation(.bouncy(duration: 0.15, extraBounce: 0.2), value: configuration.isPressed) 15 | } 16 | } 17 | 18 | struct PrimaryButton: View { 19 | let title: String 20 | let bgColor: Color 21 | let onTap: () -> Void 22 | 23 | var body: some View { 24 | Button(action: onTap, label: { 25 | ZStack { 26 | RoundedRectangle(cornerRadius: 20, style: .continuous).fill(bgColor) 27 | .frame(maxHeight: 50) 28 | .shadow(color: bgColor.opacity(0.08), radius: 2, x: 0, y: 5) 29 | Label(title, systemImage: "") 30 | .fontWeight(.bold) 31 | .foregroundColor(.white) 32 | } 33 | 34 | }) 35 | .buttonStyle(PrimaryButtonStyle()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /swiftystuff/gradientblur/DetailsButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShowDetailsButton.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct DetailsButton: View { 11 | @Binding var isShowDetails: Bool 12 | 13 | var body: some View { 14 | Button(action: { 15 | withAnimation(.easeInOut(duration: 0.3)) { 16 | isShowDetails.toggle() 17 | } 18 | }, label: { 19 | Label("Button", systemImage: isShowDetails ? "eye.slash" : "eye") 20 | .padding(10) 21 | .labelStyle(.iconOnly) 22 | .font(.system(size: 10, weight: .bold)) 23 | .tint(.white) 24 | .background( 25 | Circle() 26 | .fill(.thinMaterial) 27 | ) 28 | }) 29 | .shadow(color: .black.opacity(0.2), radius: 10, x: 0.0, y: 10) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /swiftystuff/gradientblur/GradientBlurView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProgressiveBlurView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct GradientBlurView: View { 11 | var body: some View { 12 | NavigationView { 13 | VStack { 14 | ProfileView() 15 | .padding() 16 | Text("Currently Watching") 17 | .bold() 18 | .foregroundStyle(.secondary) 19 | ScrollView(.horizontal) { 20 | LazyHStack { 21 | ForEach(movies) { movie in 22 | MovieCardView(movie: movie) 23 | .containerRelativeFrame(.horizontal, count: 1, span: 1, spacing: 0, alignment: .center) 24 | .scrollTransition { content, phase in 25 | content 26 | .opacity(phase.isIdentity ? 1 : 0) 27 | .scaleEffect(phase.isIdentity ? 1 : 0.7) 28 | .blur(radius: phase.isIdentity ? 0 : 5) 29 | .offset(y: phase.isIdentity ? 0 : 150) 30 | } 31 | } 32 | } 33 | .scrollTargetLayout() 34 | } 35 | } 36 | } 37 | .scrollTargetBehavior(.viewAligned(limitBehavior: .always)) 38 | .scrollClipDisabled() 39 | .scrollIndicators(.hidden) 40 | } 41 | } 42 | 43 | #Preview { 44 | GradientBlurView() 45 | } 46 | -------------------------------------------------------------------------------- /swiftystuff/gradientblur/Model.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Model.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import Foundation 9 | 10 | struct Movie: Identifiable { 11 | let id = UUID() 12 | let genre: String 13 | let streamingOn: String 14 | let date: String 15 | let image: String 16 | let details: String 17 | } 18 | 19 | let movies: [Movie] = [ 20 | Movie( 21 | genre: "Sci-Fi. 30 Jun 2023. 43 min", 22 | streamingOn: "Apple TV+", 23 | date: "2023. 1 Season (8.4)", 24 | image: "silo", 25 | details: "In a ruined and toxic future, thousands live in a giant silo deep underground. After its sheriff breaks a cardinal rule and residents die mysteriously, engineer Juliette starts to uncover shocking secrets and the truth about the silo." 26 | ), 27 | Movie(genre: "Comedy, Drama. 30 Mar 2023. 47 min", 28 | streamingOn: "HBO Max", 29 | date: "2023. 4 Season (8.9)", 30 | image: "succession", 31 | details: "The Roy family is known for controlling the biggest media and entertainment company in the world. However, their world changes when their father steps down from the company.."), 32 | Movie(genre: "History, Drama. 30 Jun 2019. 47 min", 33 | streamingOn: "HBO Max", 34 | date: "2019. 1 Mini Season (9.3)", 35 | image: "chernobyl", 36 | details: "In April 1986, an explosion at the Chernobyl nuclear power plant in the Union of Soviet Socialist Republics becomes one of the world's worst man-made catastrophes."), 37 | ] 38 | -------------------------------------------------------------------------------- /swiftystuff/gradientblur/MovieCardView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MovieCardView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ShowDetailsModifier: ViewModifier { 11 | @Binding var isShowDetails: Bool 12 | 13 | func body(content: Content) -> some View { 14 | content 15 | .overlay(alignment: .topTrailing) { 16 | DetailsButton(isShowDetails: $isShowDetails) 17 | .padding() 18 | } 19 | } 20 | } 21 | 22 | extension View { 23 | func withDetailsButton(_ isShowDetails: Binding) -> some View { 24 | modifier(ShowDetailsModifier(isShowDetails: isShowDetails)) 25 | } 26 | } 27 | 28 | struct MovieCardView: View { 29 | let movie: Movie 30 | @State private var isShowDetails: Bool = true 31 | 32 | var body: some View { 33 | GeometryReader { proxy in 34 | VStack(alignment: .center) { 35 | ZStack { 36 | Image(movie.image) 37 | .resizable() 38 | .clipShape(.rect(cornerRadius: 20)) 39 | .zIndex(0) 40 | .withDetailsButton($isShowDetails) 41 | 42 | if isShowDetails { 43 | Rectangle() 44 | .fill(.ultraThinMaterial) 45 | .clipShape(.rect(cornerRadius: 20)) 46 | .zIndex(1) 47 | Image(movie.image) 48 | .resizable() 49 | .clipShape(.rect(cornerRadius: 20)) 50 | .mask(LinearGradient(stops: [.init(color: .white, location: 0), 51 | .init(color: .white, location: 0.4), 52 | .init(color: .clear, location: 0.65), 53 | .init(color: .clear, location: 0.8)], 54 | startPoint: .top, endPoint: .bottom)) 55 | .zIndex(2) 56 | .withDetailsButton($isShowDetails) 57 | .overlay(alignment: .bottom) { 58 | MovieDetailsView(movie: movie) 59 | .padding() 60 | } 61 | } 62 | } 63 | .frame(width: 350, height: 520) 64 | .padding() 65 | .shadow(color: .black.opacity(0.05), radius: 10, x: 0, y: 20) 66 | } 67 | .frame(width: proxy.size.width, height: proxy.size.height) 68 | } 69 | } 70 | } 71 | 72 | #Preview { 73 | MovieCardView(movie: movies[2]) 74 | } 75 | -------------------------------------------------------------------------------- /swiftystuff/gradientblur/MovieDetailsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MovieDetailsView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MovieDetailsView: View { 11 | let movie: Movie 12 | 13 | var body: some View { 14 | VStack(spacing: 10) { 15 | VStack(spacing: 10) { 16 | Text(movie.genre) 17 | .font(.footnote) 18 | Text(movie.date) 19 | .font(.caption) 20 | } 21 | .foregroundStyle(.secondary) 22 | 23 | HStack { 24 | Button("Watch it on \(movie.streamingOn) now") {} 25 | .padding(10) 26 | .buttonStyle(.plain) 27 | .font(.system(size: 10, weight: .bold)) 28 | .background( 29 | RoundedRectangle(cornerRadius: 20.0) 30 | .fill(.ultraThickMaterial) 31 | ) 32 | Button("Save for later") {} 33 | .padding(10) 34 | .buttonStyle(.plain) 35 | .font(.system(size: 10, weight: .semibold)) 36 | .background( 37 | RoundedRectangle(cornerRadius: 20.0) 38 | .fill(.thinMaterial) 39 | ) 40 | } 41 | Text(movie.details) 42 | .font(.caption2) 43 | .foregroundStyle(.secondary) 44 | } 45 | } 46 | } 47 | 48 | #Preview { 49 | MovieDetailsView(movie: movies[0]) 50 | } 51 | -------------------------------------------------------------------------------- /swiftystuff/gradientblur/ProfileView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ProfileView: View { 11 | var body: some View { 12 | VStack { 13 | VStack { 14 | Text("SJ") 15 | .font(.largeTitle) 16 | .foregroundStyle(.white) 17 | .padding() 18 | .background( 19 | Circle() 20 | .fill(.gray.gradient) 21 | .shadow(color: .black.opacity(0.1), radius: 10, x: 0.0, y: 10) 22 | ) 23 | VStack(alignment: .center) { 24 | Text("Steve Jobs") 25 | .font(.title3) 26 | .bold() 27 | Button("View full profile") {} 28 | .font(.caption) 29 | } 30 | } 31 | } 32 | } 33 | } 34 | 35 | #Preview { 36 | ProfileView() 37 | } 38 | -------------------------------------------------------------------------------- /swiftystuff/horizontalslider/HorizontalSlider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HorizontalSlider.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 03/08/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct HorizontalSlider: View { 11 | @State private var scrollPosition: Int? = 12 12 | @State private var sliderValue = 12 13 | 14 | var body: some View { 15 | VStack { 16 | Text(String(sliderValue)) 17 | .font(.system(size: 120, weight: .bold, design: .rounded)) 18 | .contentTransition(.numericText()) 19 | ScrollView(.horizontal, showsIndicators: false) { 20 | LazyHStack(spacing: 5) { 21 | ForEach(10 ..< 50, id: \.self) { idx in 22 | SliderIndicator(index: idx) 23 | .visualEffect { content, proxy in 24 | let frame = proxy.frame(in: .scrollView(axis: .horizontal)) 25 | let distance = max(0, frame.midX) 26 | return content 27 | .opacity(distance < 200 ? 1 : 0.4) 28 | } 29 | .id(idx) 30 | } 31 | } 32 | .scrollTargetLayout() 33 | } 34 | .frame(height: 100) 35 | .overlay { TargetIndicatorView() } 36 | .background { SliderBackgroundView() } 37 | .scrollPosition(id: $scrollPosition, anchor: .center) 38 | .onChange(of: scrollPosition ?? 25) { _, newValue in 39 | withAnimation { sliderValue = newValue } 40 | } 41 | } 42 | } 43 | } 44 | 45 | #Preview { 46 | HorizontalSlider() 47 | } 48 | -------------------------------------------------------------------------------- /swiftystuff/horizontalslider/LowerIndicatorsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LowerIndicatorsView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 18/08/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | func getIndicatorHeight(idx: Int, heightDifference: CGFloat = 5.0) -> CGFloat { 11 | switch idx { 12 | case 0: 13 | return heightDifference * 2 14 | case 5: 15 | return heightDifference * 3 16 | default: 17 | return heightDifference 18 | } 19 | } 20 | 21 | struct LowerIndicatorsView: View { 22 | var body: some View { 23 | HStack(spacing: 5) { 24 | ForEach(0 ..< 10, id: \.self) { idx in 25 | RoundedRectangle(cornerRadius: 10.0) 26 | .frame(width: 2, height: getIndicatorHeight(idx: idx)) 27 | .foregroundStyle(idx == 5 ? .orange : .gray) 28 | } 29 | } 30 | } 31 | } 32 | 33 | #Preview { 34 | LowerIndicatorsView() 35 | } 36 | -------------------------------------------------------------------------------- /swiftystuff/horizontalslider/SliderView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SliderView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 18/08/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SliderBackgroundView: View { 11 | var body: some View { 12 | RoundedRectangle(cornerRadius: 2.0) 13 | .foregroundStyle(.black.opacity(0.95).gradient) 14 | } 15 | } 16 | 17 | struct SliderIndicator: View { 18 | let index: Int 19 | 20 | var body: some View { 21 | VStack { 22 | Text(String(index)) 23 | .foregroundStyle(.white) 24 | .font(.system(size: 25, weight: .semibold, design: .rounded)) 25 | LowerIndicatorsView() 26 | } 27 | } 28 | } 29 | 30 | #Preview { 31 | SliderIndicator(index: 12) 32 | } 33 | -------------------------------------------------------------------------------- /swiftystuff/horizontalslider/TargetIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TargetIndicatorView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 18/08/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TargetIndicatorView: View { 11 | var body: some View { 12 | Image(systemName: "triangle.fill") 13 | .rotationEffect(.degrees(180)) 14 | .font(.title) 15 | .foregroundStyle(.red) 16 | .offset(y: -50) 17 | } 18 | } 19 | 20 | #Preview { 21 | TargetIndicatorView() 22 | } 23 | -------------------------------------------------------------------------------- /swiftystuff/imagevariableblur/ImageUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 2025. 01. 19.. 6 | // 7 | import CoreImage 8 | import CoreImage.CIFilterBuiltins 9 | 10 | enum VariableBlurPosition { 11 | case top, bottom 12 | 13 | var colors: [CIColor] { 14 | switch self { 15 | case .top: 16 | return [.black, .white] 17 | case .bottom: 18 | return [.white, .black] 19 | } 20 | } 21 | } 22 | 23 | func maskImageWithVaribleBlur(ciImage: CIImage, mask: CIImage, blurRadius: Float) -> CIImage { 24 | let filter = CIFilter.maskedVariableBlur() 25 | 26 | filter.inputImage = ciImage 27 | filter.mask = mask 28 | filter.radius = blurRadius 29 | 30 | return filter.outputImage! 31 | } 32 | 33 | func getImageMask(maskHeight: Double, blurPosition: VariableBlurPosition) -> CIImage { 34 | // Create a mask that goes from white to black vertically. 35 | let mask = CIFilter.smoothLinearGradient() 36 | mask.color0 = blurPosition.colors[0] 37 | mask.color1 = blurPosition.colors[1] 38 | mask.point0 = CGPoint(x: 0, y: 0) 39 | mask.point1 = CGPoint(x: 0, y: maskHeight) 40 | 41 | return mask.outputImage.unsafelyUnwrapped 42 | } 43 | -------------------------------------------------------------------------------- /swiftystuff/imagevariableblur/ImageVariableBlurView.swift: -------------------------------------------------------------------------------- 1 | import CoreImage 2 | import CoreImage.CIFilterBuiltins 3 | import SwiftUI 4 | 5 | struct ImageVariableBlurView: View { 6 | @State private var image: UIImage? 7 | 8 | let imageName: String 9 | let blurRadius: Float 10 | let position: VariableBlurPosition 11 | let context = CIContext() 12 | 13 | init(imageName: String, blurRadius: Float = 25.0, position: VariableBlurPosition = .bottom) { 14 | self.imageName = imageName 15 | self.blurRadius = blurRadius 16 | self.position = position 17 | } 18 | 19 | var body: some View { 20 | VStack { 21 | if let image = image { 22 | Image(uiImage: image) 23 | .resizable() 24 | .scaledToFit() 25 | } else { 26 | ProgressView() 27 | .progressViewStyle(.circular) 28 | } 29 | } 30 | .onAppear { 31 | guard let uiImage = UIImage(named: imageName) else { return } 32 | guard let ciImage = CIImage(image: uiImage) else { return } 33 | 34 | let imageMask = getImageMask(maskHeight: ciImage.extent.height, blurPosition: self.position) 35 | let blurredImage = maskImageWithVaribleBlur(ciImage: ciImage, mask: imageMask, blurRadius: self.blurRadius) 36 | guard let cgImage = context.createCGImage(blurredImage, from: blurredImage.extent) else { return } 37 | 38 | image = UIImage(cgImage: cgImage) 39 | } 40 | } 41 | } 42 | 43 | #Preview { 44 | ImageVariableBlurView(imageName: "silo", blurRadius: 20, position: .bottom) 45 | } 46 | -------------------------------------------------------------------------------- /swiftystuff/longpressbutton/LongPressButtonView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeleteButtonView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 22/10/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct LongPressButtonView: View { 11 | @State private var isPressing = false 12 | @State private var isPressed = false 13 | 14 | let gestureDuration: TimeInterval = 1 15 | let accentColor: Color = .green 16 | let systemImage: String = "tree.fill" 17 | let buttonText: String = "Tree mode" 18 | 19 | var body: some View { 20 | ZStack(alignment: .center) { 21 | Circle() 22 | .fill(.green) 23 | .frame(width: isPressed ? 1000 : 0, height: isPressed ? 1000 : 0) 24 | .opacity(isPressed ? 0.1 : 0) 25 | VStack(spacing: 10) { 26 | Image(systemName: systemImage) 27 | .font(.system(size: 25)) 28 | .scaleEffect(isPressing || isPressed ? 2 : 1) 29 | .symbolRenderingMode(isPressed ? .monochrome : .multicolor) 30 | .symbolEffect(.bounce, value: isPressed) 31 | 32 | if !isPressing && !isPressed { 33 | Text(buttonText) 34 | .font(.system(size: 12, weight: .bold, design: .rounded)) 35 | .transition(.move(edge: .bottom).combined(with: .blurReplace)) 36 | } 37 | } 38 | .frame(width: 100, height: 100) 39 | .foregroundStyle(isPressed ? .white : .gray) 40 | .background( 41 | ZStack(alignment: .leading) { 42 | RoundedRectangle(cornerRadius: 20, style: .continuous) 43 | .fill(isPressed ? accentColor : .gray.opacity(0.15)) 44 | Rectangle() 45 | .frame(width: isPressing ? 150 : 10, height: 100) 46 | .opacity(isPressing ? 0.1 : 0) 47 | } 48 | ) 49 | .clipShape(.rect(cornerRadius: 20)) 50 | .onLongPressGesture(minimumDuration: gestureDuration) { 51 | withAnimation(.bouncy) { 52 | isPressed.toggle() 53 | } 54 | 55 | } onPressingChanged: { isPressing in 56 | withAnimation(.spring(duration: gestureDuration)) { 57 | self.isPressing = isPressing 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | #Preview { 65 | LongPressButtonView() 66 | } 67 | -------------------------------------------------------------------------------- /swiftystuff/meshgradientbutton/MeshGradientButtonView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProgressButton.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 12/10/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | private struct MeshAnimationColors { 11 | let points: [SIMD2] 12 | let colors: [Color] 13 | let name: String 14 | } 15 | 16 | private enum MeshAnimationPhase { 17 | case initial, processing, done 18 | 19 | @available(iOS 18.0, *) 20 | var value: MeshAnimationColors { 21 | switch self { 22 | case .initial: 23 | return .init(points: 24 | [ 25 | [0.0, 0.0], [0.5, 0.0], [1.0, 0.0], 26 | [0.0, 0.5], [0.8, 0.2], [1.0, 0.5], 27 | [0.0, 1.0], [0.5, 1.0], [1.0, 1.0], 28 | ], colors: [ 29 | .purple, .red, .purple, 30 | .purple, .orange, .purple, 31 | .pink, .red, .pink, 32 | ], name: "Verify") 33 | case .processing: 34 | return .init(points: 35 | [ 36 | [0.0, 0.0], [0.5, 0.0], [1.0, 0.0], 37 | [0.0, 0.5], [0.3, 0.2], [1.0, 0.5], 38 | [0.0, 1.0], [0.5, 1.0], [1.0, 1.0], 39 | ], colors: [ 40 | .red, .orange, .indigo, 41 | .red, .red, .orange, 42 | .green, .green, .green, 43 | ], name: "Verifying") 44 | 45 | case .done: 46 | return .init(points: 47 | [ 48 | [0.0, 0.0], [0.5, 0.0], [1.0, 0.0], 49 | [0.0, 0.5], [0.1, 0.8], [1.0, 0.5], 50 | [0.0, 1.0], [0.5, 1.0], [1.0, 1.0], 51 | ], colors: [ 52 | .blue, .indigo, .cyan, 53 | .green, .green, .green, 54 | .green, .green, .green, 55 | ], name: "Verified") 56 | } 57 | } 58 | } 59 | 60 | @available(iOS 18.0, *) 61 | private struct ButtonTextView: View { 62 | @Binding var phase: MeshAnimationPhase 63 | 64 | var body: some View { 65 | HStack { 66 | Text(phase.value.name) 67 | .contentTransition(.numericText()) 68 | switch phase { 69 | case .initial: 70 | Image(systemName: "exclamationmark.circle.fill") 71 | .symbolEffect(.wiggle, options: .repeat(.continuous), isActive: true) 72 | case .processing: 73 | Image(systemName: "ellipsis") 74 | .symbolEffect(.variableColor, options: .repeat(.continuous), isActive: true) 75 | case .done: 76 | Image(systemName: "checkmark.seal.fill") 77 | .symbolEffect(.bounce, options: .repeat(1), isActive: true) 78 | } 79 | } 80 | .shadow(color: .black.opacity(0.1), radius: 10, x: 0, y: 10) 81 | .font(.system(size: 20, weight: .bold, design: .rounded)) 82 | .foregroundStyle(.white) 83 | } 84 | } 85 | 86 | @available(iOS 18.0, *) 87 | struct MeshGradientButtonView: View { 88 | @State private var phase: MeshAnimationPhase = .initial 89 | 90 | var body: some View { 91 | VStack { 92 | Capsule(style: .continuous) 93 | .fill( 94 | MeshGradient(width: 3, height: 3, points: phase.value.points, colors: phase.value.colors) 95 | ) 96 | .overlay { 97 | ButtonTextView(phase: $phase) 98 | } 99 | .frame(width: 300, height: 70) 100 | .onTapGesture { 101 | withAnimation(.smooth(duration: 1, extraBounce: 0.5)) { 102 | switch phase { 103 | case .initial: 104 | self.phase = .processing 105 | case .processing: 106 | self.phase = .done 107 | case .done: 108 | self.phase = .initial 109 | } 110 | } 111 | } 112 | .contentShape(.capsule) 113 | } 114 | } 115 | } 116 | 117 | #Preview { 118 | if #available(iOS 18.0, *) { 119 | MeshGradientButtonView() 120 | } else { 121 | // Fallback on earlier versions 122 | Text("This view is only available in iOS 18 and newer") 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /swiftystuff/otherstuffs/VelocityHorizontalScroll.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 19/10/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @available(iOS 18.0, *) 11 | struct HorizontalScrollingView: View { 12 | @State private var lastOffset: CGPoint = .zero 13 | @State private var lastTime: Date = .init() 14 | 15 | @State private var velocityX: CGFloat = .zero 16 | @State private var velocityY: CGFloat = .zero 17 | 18 | func calculateVelocity(currentOffset: CGPoint) { 19 | let timeInterval = Date().timeIntervalSince(lastTime) 20 | if timeInterval > 0.1 { 21 | let offsetDifference = CGPoint( 22 | x: currentOffset.x - lastOffset.x, 23 | y: currentOffset.y - lastOffset.y 24 | ) 25 | 26 | // Calculate the velocity using the offset difference and time interval 27 | 28 | velocityX = offsetDifference.x / CGFloat(timeInterval) 29 | velocityY = offsetDifference.y / CGFloat(timeInterval) 30 | } 31 | } 32 | 33 | var body: some View { 34 | VStack { 35 | Text("velocity Y: \(velocityY), velocity X: \(velocityX)") 36 | 37 | ScrollView(.horizontal) { 38 | HStack(spacing: 20) { 39 | ForEach(0 ..< 100) { index in 40 | Text("Item \(index)") 41 | .padding() 42 | .background(Color.gray.opacity(0.2)) 43 | .cornerRadius(10) 44 | .rotationEffect(.degrees(velocityX / 100)) 45 | } 46 | } 47 | .scrollTargetLayout() 48 | .padding() 49 | } 50 | .onScrollPhaseChange { _, newPhase, ctx in 51 | print(newPhase) 52 | if newPhase == .interacting { 53 | self.calculateVelocity(currentOffset: ctx.geometry.contentOffset) 54 | } else if newPhase == .decelerating { 55 | self.calculateVelocity(currentOffset: ctx.geometry.contentOffset) 56 | } else if newPhase == .idle { 57 | lastOffset = ctx.geometry.contentOffset 58 | lastTime = .init() 59 | 60 | velocityX = .zero 61 | velocityY = .zero 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | #Preview { 69 | if #available(iOS 18.0, *) { 70 | HorizontalScrollingView() 71 | } else { 72 | // Fallback on earlier versions 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /swiftystuff/revealingbutton/ButtonCircularProgressView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonCircularProgressView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 07/09/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ButtonCircularProgressView: View { 11 | @Binding var isPressing: Bool 12 | @Binding var isShowing: Bool 13 | 14 | var body: some View { 15 | Circle() 16 | .rotation(.degrees(270)) 17 | .trim(from: 0.0, to: isPressing || isShowing ? 1.2 : 0.0) 18 | .stroke(style: .init(lineWidth: 2, lineCap: .round)) 19 | .foregroundStyle(isPressing ? .green : .orange) 20 | .opacity(isShowing && !isPressing ? 0 : 1) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /swiftystuff/revealingbutton/ButtonsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonsView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 07/09/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ButtonsView: View { 11 | var body: some View { 12 | VStack { 13 | IconButton(systemImage: "menucard.fill", color: .purple) 14 | IconButton(systemImage: "lasso", color: .orange) 15 | IconButton(systemImage: "dumbbell.fill", color: .blue) 16 | IconButton(systemImage: "doc.append.fill.rtl", color: .red) 17 | } 18 | .transition(.asymmetric(insertion: .scale.combined(with: .offset(y: 50)), removal: .scale.combined(with: .opacity))) 19 | } 20 | } 21 | 22 | private struct IconButton: View { 23 | let text = "" 24 | let systemImage: String 25 | let color: Color 26 | 27 | var body: some View { 28 | Button(text, systemImage: systemImage) {} 29 | .foregroundStyle(color) 30 | .padding(10) 31 | .labelStyle(.iconOnly) 32 | .background(Circle().foregroundStyle(color.opacity(0.2))) 33 | } 34 | } 35 | 36 | #Preview { 37 | ButtonsView() 38 | } 39 | -------------------------------------------------------------------------------- /swiftystuff/revealingbutton/RevealingButtonModifier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonPressModifier.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 07/09/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RevealingButtonModifier: ViewModifier { 11 | @Binding var isShowing: Bool 12 | @Binding var isPressing: Bool 13 | @Binding var isShowingCircularProgress: Bool 14 | 15 | func body(content: Content) -> some View { 16 | content 17 | .foregroundStyle(isPressing || isShowing ? .orange : .purple) 18 | .rotationEffect(.degrees(isPressing || isShowing ? 135 : 0)) 19 | .overlay(ButtonCircularProgressView(isPressing: $isShowingCircularProgress, isShowing: $isShowing)) 20 | .font(.largeTitle) 21 | .symbolEffect(.bounce, value: isShowing) 22 | .scaleEffect(isShowing || isPressing ? 1.5 : 1) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /swiftystuff/revealingbutton/RevealingButtonView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RevealingButtonView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/08/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RevealingButtonView: View { 11 | @State private var isShowing = false 12 | @State private var isShowingCircularProgress = false 13 | @State private var isPressing = false 14 | 15 | let gestureDuration = 1.0 16 | 17 | func handleGestureFinished() { 18 | withAnimation(.spring) { 19 | self.isShowing.toggle() 20 | } 21 | } 22 | 23 | func handleIsPressingButton(_ isPressing: Bool) { 24 | withAnimation(.bouncy(extraBounce: 0.1)) { 25 | if isPressing && isShowing { 26 | isShowing = false 27 | return 28 | } 29 | 30 | self.isPressing = isPressing 31 | toggleShowCircularProgress(isPressing) 32 | } 33 | } 34 | 35 | func toggleShowCircularProgress(_ isPressing: Bool) { 36 | withAnimation(.linear(duration: gestureDuration)) { 37 | self.isShowingCircularProgress = isPressing 38 | } 39 | } 40 | 41 | var body: some View { 42 | VStack(spacing: 15) { 43 | if isShowing { 44 | ButtonsView() 45 | } 46 | ZStack { 47 | Label("Add something", systemImage: "plus.circle.fill") 48 | .modifier(RevealingButtonModifier(isShowing: $isShowing, isPressing: $isPressing, isShowingCircularProgress: $isShowingCircularProgress)) 49 | .onLongPressGesture(minimumDuration: gestureDuration) { 50 | handleGestureFinished() 51 | } onPressingChanged: { isPressing in 52 | handleIsPressingButton(isPressing) 53 | } 54 | } 55 | } 56 | .labelStyle(.iconOnly) 57 | } 58 | } 59 | 60 | #Preview { 61 | RevealingButtonView() 62 | } 63 | -------------------------------------------------------------------------------- /swiftystuff/scrollingstackview/ScollingStackView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScollingStackView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 23/06/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ScollingStackView: View { 11 | var body: some View { 12 | ScrollView { 13 | LazyVStack { 14 | ForEach(0 ..< 20) { _ in 15 | RoundedRectangle(cornerRadius: 24) 16 | .fill(.blue) 17 | .frame(height: 100) 18 | .visualEffect { content, proxy in 19 | let frame = proxy.frame(in: .scrollView(axis: .vertical)) 20 | let _ = proxy 21 | .bounds(of: .scrollView(axis: .vertical)) ?? 22 | .infinite 23 | 24 | // The distance this view extends past the bottom edge 25 | // of the scroll view. 26 | let distance = min(0, frame.minY) 27 | 28 | return content 29 | .hueRotation(.degrees(frame.origin.y / 20)) 30 | .scaleEffect(1 + distance / 800) 31 | .offset(y: -distance / 1.25) 32 | .brightness(-distance / 400) 33 | .blur(radius: -distance / 50) 34 | } 35 | } 36 | } 37 | .padding() 38 | } 39 | } 40 | } 41 | 42 | #Preview { 43 | ScollingStackView() 44 | } 45 | -------------------------------------------------------------------------------- /swiftystuff/simplepicker/PickerButtonView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PickerButtonView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 2025. 01. 18.. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct PickerButton: View { 11 | let title: String 12 | 13 | @Binding var selected: [String] 14 | @State private var isSelected: Bool = false 15 | 16 | var body: some View { 17 | HStack { 18 | if isSelected { 19 | Image(systemName: "checkmark.circle.fill") 20 | .foregroundStyle(.green) 21 | .symbolEffect(.bounce, value: isSelected) 22 | } 23 | Text(title) 24 | .font(.system(size: 15, weight: .semibold, design: .rounded)) 25 | } 26 | .padding(10) 27 | .background( 28 | RoundedRectangle(cornerRadius: 15, style: .continuous) 29 | .stroke(isSelected ? .green : .secondary, style: .init(lineWidth: isSelected ? 2 : 1, lineCap: .round, lineJoin: .round)) 30 | ) 31 | .onTapGesture { 32 | withAnimation(.bouncy(duration: 0.2, extraBounce: 0.3)) { 33 | isSelected.toggle() 34 | selected.append(title.lowercased()) 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /swiftystuff/simplepicker/SimplePickerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SimplePickerView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 2025. 01. 16.. 6 | // 7 | 8 | import SwiftUI 9 | 10 | private struct PickerModalView: View { 11 | @Binding var isShowModal: Bool 12 | @State private var selected: [String] = [] 13 | 14 | var body: some View { 15 | GeometryReader { proxy in 16 | VStack(alignment: .leading) { 17 | Text("Select tags") 18 | .font(.title3) 19 | .bold() 20 | Spacer() 21 | Text("Recently used") 22 | .font(.caption) 23 | .foregroundStyle(.secondary) 24 | VStack(alignment: .leading, spacing: 10) { 25 | HStack { 26 | PickerButton(title: "Inspiration", selected: $selected) 27 | PickerButton(title: "Imporatant", selected: $selected) 28 | PickerButton(title: "Later", selected: $selected) 29 | } 30 | HStack { 31 | PickerButton(title: "Gym", selected: $selected) 32 | PickerButton(title: "Idea", selected: $selected) 33 | PickerButton(title: "Work", selected: $selected) 34 | PickerButton(title: "Job", selected: $selected) 35 | } 36 | } 37 | Spacer() 38 | PrimaryButton(title: "Done", bgColor: .primary) { 39 | isShowModal.toggle() 40 | } 41 | } 42 | .padding(25) 43 | .frame(width: proxy.size.width) 44 | } 45 | } 46 | } 47 | 48 | struct SimplePickerView: View { 49 | @State private var isShowPicker = false 50 | 51 | var body: some View { 52 | VStack { 53 | ScrollView { 54 | VStack { 55 | ForEach(sampleContents) { content in TextContentView(content: content) } 56 | } 57 | .padding() 58 | } 59 | PrimaryButton(title: "Add Tags", bgColor: .purple) { isShowPicker.toggle() } 60 | .padding() 61 | } 62 | .sheet(isPresented: $isShowPicker) { 63 | PickerModalView(isShowModal: $isShowPicker) 64 | .presentationBackground(.linearGradient(colors: [Color.clear, .purple.opacity(0.5)], startPoint: .top, endPoint: .bottom)) 65 | .presentationDetents([.height(300)]) 66 | .frame(maxWidth: .infinity, maxHeight: .infinity) 67 | .background(.white) 68 | .clipShape(.rect(cornerRadius: 30.0)) 69 | .padding() 70 | } 71 | } 72 | } 73 | 74 | #Preview { 75 | SimplePickerView() 76 | } 77 | -------------------------------------------------------------------------------- /swiftystuff/simplepicker/TextContentModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextContentModel.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 2025. 01. 18.. 6 | // 7 | 8 | import Foundation 9 | 10 | struct TextContentModel: Identifiable { 11 | let id = UUID() 12 | let title: String 13 | let description: String 14 | let iconName: String 15 | } 16 | 17 | let sampleContents = [ 18 | TextContentModel(title: "New years resolution", description: """ 19 | Hold a Lorem Ipsum scavenger hunt on your newly-launched website after any updates. Provide cash or prizes to all users who highlight any Lorem Ipsum text your final edits missed. Do the same for missing, misused, or misspelled words. Your web page analytics will skyrocket as these grammatical and stylistic errors disappear, and your opening rates, conversions, and profits will soar. 20 | 21 | Visit each of the Lorem Ipsum generators listed and test them for yourself. Use each to create separate web pages, emails, ads, and social media posts. Keep trying each generator until you feel comfortable using it. When ready, create themes and templates to sell to fellow content creators. 22 | """, iconName: "balloon.2"), 23 | TextContentModel(title: "End of the year party", description: """ 24 | Visit each of the Lorem Ipsum generators listed and test them for yourself. Use each to create separate web pages, emails, ads, and social media posts. Keep trying each generator until you feel comfortable using it. When ready, create themes and templates to sell to fellow content creators. 25 | """, iconName: "figure.socialdance"), 26 | TextContentModel(title: "Marathon", description: """ 27 | In SwiftUI, if you want a view to fill the available width and height of its container without explicitly specifying those values, you can rely on layout modifiers that adapt to the container's size 28 | """, iconName: "figure.run") 29 | ] -------------------------------------------------------------------------------- /swiftystuff/simplepicker/TextContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextContentView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 2025. 01. 18.. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TextContentView: View { 11 | let content: TextContentModel 12 | 13 | var body: some View { 14 | HStack(alignment: .top) { 15 | VStack { 16 | Image(systemName: content.iconName) 17 | .foregroundStyle(.secondary) 18 | RoundedRectangle(cornerRadius: 10.0) 19 | .frame(width: 1.5) 20 | .foregroundStyle(.tertiary) 21 | } 22 | VStack(alignment: .leading) { 23 | Text(content.title) 24 | .font(.system(.headline, design: .rounded, weight: .semibold)) 25 | Text("31 Dec 2024") 26 | .font(.caption2) 27 | .foregroundStyle(.secondary) 28 | Text(content.description) 29 | .font(.subheadline) 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /swiftystuff/swiftystuffApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // swiftystuffApp.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/01/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct swiftystuffApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/TabBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarContentView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 04/05/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WithTabBar: View where Content: View { 11 | @State private var selection: Tabs = .home 12 | @ViewBuilder var content: (Tabs) -> Content 13 | 14 | var body: some View { 15 | GeometryReader { proxy in 16 | ZStack { 17 | content(selection) 18 | } 19 | .frame(width: proxy.size.width, height: proxy.size.height) 20 | .overlay(alignment: .bottom) { 21 | TabBar(selection: $selection) 22 | .padding() 23 | } 24 | } 25 | } 26 | } 27 | 28 | struct TabBar: View { 29 | @Binding var selection: Tabs 30 | @State private var symbolTrigger: Bool = true 31 | @Namespace private var tabItemNameSpace 32 | 33 | func changeTabTo(_ tab: Tabs) { 34 | withAnimation(.bouncy(duration: 0.3, extraBounce: 0.15)) { 35 | selection = tab 36 | } 37 | symbolTrigger.toggle() 38 | } 39 | 40 | var body: some View { 41 | HStack(spacing: 10) { 42 | ForEach(Tabs.allCases, id: \.self) { tab in 43 | Button(action: { 44 | changeTabTo(tab) 45 | }) { 46 | if tab == selection { 47 | ActiveTabLabel(tabItem: tab.item) 48 | .matchedGeometryEffect(id: "tabItem", in: tabItemNameSpace) 49 | } else { 50 | InActiveTabLabel(tabItem: tab.item) 51 | } 52 | } 53 | .symbolEffect(.bounce.up.byLayer, value: symbolTrigger) 54 | .foregroundStyle(tab.item.color) 55 | .withTabButtonStyle() 56 | } 57 | } 58 | .padding(10) 59 | .background(.regularMaterial) 60 | .clipShape(RoundedRectangle(cornerRadius: 35.0)) 61 | .shadow(color: .black.opacity(0.05), radius: 5, x: 0, y: 5) 62 | } 63 | } 64 | 65 | #Preview { 66 | WithTabBar { selection in 67 | Text("Hello world") 68 | .foregroundStyle(selection.item.color) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/TabBarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 21/04/2024. 6 | // 7 | 8 | import MapKit 9 | import SwiftUI 10 | 11 | struct TabBarView: View { 12 | var body: some View { 13 | WithTabBar { selection in 14 | switch selection { 15 | case .home: 16 | TabScrollContentView(tab: .home) 17 | case .discover: 18 | TabScrollContentView(tab: .discover) 19 | case .profile: 20 | TabScrollContentView(tab: .profile) 21 | case .settings: 22 | TabScrollContentView(tab: .settings) 23 | } 24 | } 25 | } 26 | } 27 | 28 | #Preview { 29 | TabBarView() 30 | } 31 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/TabButtonLabelsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabButtonLabelsView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 04/05/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | let BTTN_HEIGHT: CGFloat = 50 11 | let CORNER_RADIUS: CGFloat = 35.0 12 | 13 | struct ActiveTabLabel: View { 14 | let tabItem: TabItem 15 | 16 | var body: some View { 17 | ZStack { 18 | RoundedRectangle(cornerRadius: CORNER_RADIUS) 19 | .fill(tabItem.color.opacity(0.1)) 20 | .shadow(color: .primary.opacity(0.5), radius: 3, x: 0, y: 5) 21 | .frame(width: 120, height: BTTN_HEIGHT) 22 | Label(tabItem.title, systemImage: tabItem.systemImage) 23 | .labelStyle(.titleAndIcon) 24 | } 25 | } 26 | } 27 | 28 | struct InActiveTabLabel: View { 29 | let tabItem: TabItem 30 | 31 | var body: some View { 32 | ZStack { 33 | RoundedRectangle(cornerRadius: CORNER_RADIUS) 34 | .fill(.clear) 35 | .frame(width: 50, height: BTTN_HEIGHT) 36 | Label(tabItem.title, systemImage: tabItem.systemImage) 37 | .labelStyle(.iconOnly) 38 | .symbolEffectsRemoved() 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/TabButtonStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabButtonStyle.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 28/04/2024. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct TabButtonStyle: ButtonStyle { 12 | func makeBody(configuration: Configuration) -> some View { 13 | configuration.label 14 | .scaleEffect(configuration.isPressed ? 0.9 : 1) 15 | .opacity(configuration.isPressed ? 0.9 : 1) 16 | } 17 | } 18 | 19 | extension View { 20 | func withTabButtonStyle() -> some View { 21 | buttonStyle(TabButtonStyle()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/TabItemModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabItemModel.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 28/04/2024. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct TabItem: Identifiable, Hashable { 12 | let id = UUID() 13 | let title: String 14 | let systemImage: String 15 | let color: Color 16 | } 17 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/TabScrollContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabScrollContentView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 04/05/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TabScrollContentView: View { 11 | let tab: Tabs 12 | 13 | var body: some View { 14 | NavigationView { 15 | ScrollView { 16 | LazyVStack { 17 | ForEach((1 ... 3).reversed(), id: \.self) { _ in 18 | RoundedRectangle(cornerRadius: 25) 19 | .fill(tab.item.color.opacity(0.5)) 20 | .frame(height: 180) 21 | .scrollTransition { content, phase in 22 | content 23 | .scaleEffect(phase.isIdentity ? 1 : 0.8) 24 | .blur(radius: phase.isIdentity ? 0 : 10) 25 | } 26 | } 27 | } 28 | .padding() 29 | } 30 | .navigationTitle(tab.item.title) 31 | } 32 | } 33 | } 34 | 35 | #Preview { 36 | TabScrollContentView(tab: .home) 37 | } 38 | -------------------------------------------------------------------------------- /swiftystuff/tabbar/Tabs.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tabs.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 04/05/2024. 6 | // 7 | 8 | import Foundation 9 | 10 | enum Tabs: CaseIterable { 11 | case home, discover, profile, settings 12 | var item: TabItem { 13 | switch self { 14 | case .home: 15 | .init(title: "Home", systemImage: "house", color: .blue) 16 | case .discover: 17 | .init(title: "Discover", systemImage: "sparkles", color: .red) 18 | case .profile: 19 | .init(title: "Profile", systemImage: "person", color: .purple) 20 | case .settings: 21 | .init(title: "Settings", systemImage: "gear", color: .orange) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /swiftystuff/verticalscrollview/VerticalScrollingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewAlignedScrollView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CustomScrollTargetBehavior: ScrollTargetBehavior { 11 | func updateTarget(_ target: inout ScrollTarget, context: ViewAlignedScrollTargetBehavior.TargetContext) { 12 | // customize scroll target behavior 13 | } 14 | } 15 | 16 | struct VerticalScrollingView: View { 17 | var body: some View { 18 | GeometryReader { geometry in 19 | ScrollView(.vertical) { 20 | LazyVStack { 21 | ForEach(words) { word in 22 | ZStack { 23 | Color(Color("bgColor")) 24 | .frame(width: geometry.size.width, height: geometry.size.height, alignment: .center) 25 | WordDetailsView(word: word) 26 | } 27 | .scrollTransition { content, phase in 28 | content 29 | .scaleEffect(phase.isIdentity ? 1 : 0.5) 30 | .blur(radius: phase.isIdentity ? 0 : 20) 31 | } 32 | } 33 | } 34 | .scrollTargetLayout() 35 | } 36 | } 37 | .background(Color("bgColor")) 38 | .ignoresSafeArea(.all) 39 | .scrollIndicators(.hidden) 40 | .scrollTargetBehavior(.viewAligned(limitBehavior: .always)) 41 | } 42 | } 43 | 44 | #Preview { 45 | VerticalScrollingView() 46 | } 47 | -------------------------------------------------------------------------------- /swiftystuff/verticalscrollview/WordDetailsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WordDetailsView.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WordDetailsView: View { 11 | let word: Word 12 | 13 | @State private var isShowDetails: Bool = false 14 | @State private var isSaved: Bool = true 15 | 16 | var body: some View { 17 | VStack(alignment: .leading, spacing: 20) { 18 | HStack { 19 | Text(word.partOfSpeech) 20 | .fontWeight(.light) 21 | .foregroundStyle(.secondary) 22 | Spacer() 23 | Image(systemName: isSaved ? "bookmark.fill" : "bookmark") 24 | .foregroundStyle(.red) 25 | .onTapGesture { 26 | withAnimation { isSaved.toggle() } 27 | } 28 | } 29 | 30 | Text(word.title) 31 | .font(.largeTitle) 32 | .bold() 33 | .shadow(color: .black.opacity(0.15), radius: 8, x: 0, y: 10) 34 | .onTapGesture { isShowDetails.toggle() } 35 | HStack { 36 | Button("Play Sound", systemImage: "speaker.wave.3.fill") {} 37 | .tint(.primary) 38 | .labelStyle(.iconOnly) 39 | .buttonStyle(.bordered) 40 | Text(word.phonetic) 41 | .foregroundStyle(.secondary) 42 | } 43 | } 44 | .padding(20) 45 | .fontDesign(.serif) 46 | } 47 | } 48 | 49 | #Preview { 50 | WordDetailsView(word: words[0]) 51 | } 52 | -------------------------------------------------------------------------------- /swiftystuff/verticalscrollview/WordModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WordModel.swift 3 | // swiftystuff 4 | // 5 | // Created by Abdulrahim Illo on 20/04/2024. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | struct Word: Identifiable { 12 | let id = UUID() 13 | let title: String 14 | let partOfSpeech: String 15 | let phonetic: String 16 | } 17 | 18 | let words = [ 19 | Word(title: "imminent", partOfSpeech: "adjective", phonetic: "/ˈɪmɪnənt/"), 20 | Word(title: "altruistic", partOfSpeech: "adjective", phonetic: "/ˌæl.tɹuˈɪs.tɪk/"), 21 | Word(title: "comeuppance", partOfSpeech: "adjective", phonetic: "/kʌmˈʌpəns/"), 22 | Word(title: "punctilious", partOfSpeech: "adjective", phonetic: "/pʌŋkˈtɪli.əs/"), 23 | Word(title: "vespertine", partOfSpeech: "adjective", phonetic: "/ˈvɛspəɹtɪn/"), 24 | Word(title: "calumnies", partOfSpeech: "adjective", phonetic: "/kˈælʌmniz/") 25 | ] 26 | --------------------------------------------------------------------------------