├── .DS_Store ├── SwiftUITutorials.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcuserdata │ │ └── vb.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ └── SwiftUITutorials.xcscheme └── xcuserdata │ └── vb.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── SwiftUITutorials ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Image.imageset │ │ └── Contents.json │ ├── color_random.colorset │ │ └── Contents.json │ └── snnm.imageset │ │ ├── Contents.json │ │ └── snnm.png ├── Basket │ └── BasketDetailViewModel.swift ├── ContentView.swift ├── Core │ └── Extension │ │ ├── Logging+AFError.swift │ │ └── Navigaton+View.swift ├── Features │ ├── .DS_Store │ ├── CustomTabView │ │ ├── CustomTabIndex.swift │ │ └── CustomTabView.swift │ ├── Enıroment │ │ ├── DateControlView.swift │ │ ├── EnviromentView.swift │ │ └── Spacer+Constant.swift │ ├── FoxViewModel │ │ ├── Model │ │ │ └── FoxModel.swift │ │ ├── Service │ │ │ └── FoxService.swift │ │ ├── View │ │ │ └── RandomFoxView.swift │ │ └── ViewModel │ │ │ └── FoxViewModel.swift │ ├── Market │ │ ├── Home │ │ │ ├── MarketHomeView.swift │ │ │ ├── Model │ │ │ │ └── MarketItem.swift │ │ │ └── ViewModel │ │ │ │ └── MarketViewModel.swift │ │ └── HomeDetail │ │ │ ├── MarketDetailView.swift │ │ │ └── MarketDetailViewModel.swift │ ├── ModelList │ │ ├── ModelListView.swift │ │ ├── TweetCards.swift │ │ └── TweetModel.swift │ ├── Navigation │ │ ├── NavigationUserModel.swift │ │ ├── NavigationUsers.swift │ │ └── UserViewDetail.swift │ ├── PropertyWrapper │ │ ├── NumberCaseWrapper.swift │ │ ├── PropetyWrapperView.swift │ │ ├── UpperCaseWrapper.swift │ │ └── UserWrapperModel.swift │ ├── ReqResViewModel │ │ ├── Model │ │ │ └── User.swift │ │ ├── Service │ │ │ └── UserService.swift │ │ ├── View │ │ │ └── UserView.swift │ │ └── ViewModel │ │ │ └── UserViewModel.swift │ └── SampleListView.swift ├── Info.plist ├── Localizable │ ├── LocaleKeys.swift │ └── WelcomeView.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── SwiftUITutorialsApp.swift ├── View │ ├── 19July │ │ ├── LabelView.swift │ │ ├── TabGestureView.swift │ │ ├── TextEditingView.swift │ │ └── TimerView.swift │ ├── Circle │ │ └── CircleTextImageView.swift │ ├── TestView.swift │ ├── en.lproj │ │ └── Localizable.strings │ └── tr.lproj │ │ └── Localizable.strings └── ViewModifier │ ├── HelloView.swift │ └── View+Style.swift ├── en.lproj └── Localizable.strings └── tr.lproj └── Localizable.strings /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/SwiftUITutorials/f2a174d11a40207b546de56e248485e2fe906fea/.DS_Store -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 350382D3281F6A46000A16F7 /* RandomFoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350382D2281F6A46000A16F7 /* RandomFoxView.swift */; }; 11 | 350382D5281F6C3F000A16F7 /* FoxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350382D4281F6C3F000A16F7 /* FoxModel.swift */; }; 12 | 350382D7281F6C79000A16F7 /* FoxService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350382D6281F6C79000A16F7 /* FoxService.swift */; }; 13 | 350382DA281F6CE7000A16F7 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 350382D9281F6CE7000A16F7 /* Alamofire */; }; 14 | 350382DD281F6F0E000A16F7 /* FoxViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350382DC281F6F0E000A16F7 /* FoxViewModel.swift */; }; 15 | 350382E0281F70EF000A16F7 /* ActivityIndicatorView in Frameworks */ = {isa = PBXBuildFile; productRef = 350382DF281F70EF000A16F7 /* ActivityIndicatorView */; }; 16 | 350F8BAE2858045A00193C2D /* Navigaton+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 350F8BAD2858045900193C2D /* Navigaton+View.swift */; }; 17 | 3518296B270A5FEB0086818B /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 3518296A270A5FEB0086818B /* Kingfisher */; }; 18 | 3518296F270A62840086818B /* CircleTextImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3518296E270A62840086818B /* CircleTextImageView.swift */; }; 19 | 35568920286A754800F37779 /* PropetyWrapperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3556891F286A754800F37779 /* PropetyWrapperView.swift */; }; 20 | 35568922286A756200F37779 /* UserWrapperModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35568921286A756200F37779 /* UserWrapperModel.swift */; }; 21 | 35568924286A75AC00F37779 /* UpperCaseWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35568923286A75AC00F37779 /* UpperCaseWrapper.swift */; }; 22 | 35568926286A775600F37779 /* NumberCaseWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35568925286A775600F37779 /* NumberCaseWrapper.swift */; }; 23 | 3568CDD3276FD6B500464155 /* CustomTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3568CDD2276FD6B500464155 /* CustomTabView.swift */; }; 24 | 3568CDD5276FD8F100464155 /* CustomTabIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3568CDD4276FD8F000464155 /* CustomTabIndex.swift */; }; 25 | 357039E927B339D800B2AE4D /* EnviromentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357039E827B339D800B2AE4D /* EnviromentView.swift */; }; 26 | 357039EB27B33A9700B2AE4D /* Spacer+Constant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357039EA27B33A9700B2AE4D /* Spacer+Constant.swift */; }; 27 | 357039EF27B33F1100B2AE4D /* DateControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357039EE27B33F1100B2AE4D /* DateControlView.swift */; }; 28 | 3577D0CD28458AD600159ABA /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3577D0CC28458AD600159ABA /* User.swift */; }; 29 | 3577D0CF28458B0400159ABA /* UserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3577D0CE28458B0400159ABA /* UserService.swift */; }; 30 | 3577D0D328458CCF00159ABA /* Logging+AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3577D0D228458CCF00159ABA /* Logging+AFError.swift */; }; 31 | 3577D0D628458D5400159ABA /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 3577D0D528458D5400159ABA /* Logging */; }; 32 | 3577D0D828458EFC00159ABA /* UserViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3577D0D728458EFC00159ABA /* UserViewModel.swift */; }; 33 | 3577D0DC2845900800159ABA /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3577D0DB2845900800159ABA /* UserView.swift */; }; 34 | 357F7D7826D30FE2004182D6 /* SwiftUITutorialsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357F7D7726D30FE2004182D6 /* SwiftUITutorialsApp.swift */; }; 35 | 357F7D7A26D30FE2004182D6 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357F7D7926D30FE2004182D6 /* ContentView.swift */; }; 36 | 357F7D7C26D30FE4004182D6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 357F7D7B26D30FE4004182D6 /* Assets.xcassets */; }; 37 | 357F7D7F26D30FE4004182D6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 357F7D7E26D30FE4004182D6 /* Preview Assets.xcassets */; }; 38 | 3584539C27139F13006C3225 /* SampleListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3584539B27139F13006C3225 /* SampleListView.swift */; }; 39 | 3596D82F288602C100B55654 /* TimerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3596D82E288602C100B55654 /* TimerView.swift */; }; 40 | 3596D8312886072E00B55654 /* TextEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3596D8302886072E00B55654 /* TextEditingView.swift */; }; 41 | 3596D8332886085D00B55654 /* LabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3596D8322886085D00B55654 /* LabelView.swift */; }; 42 | 3596D835288609BF00B55654 /* TabGestureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3596D834288609BF00B55654 /* TabGestureView.swift */; }; 43 | 35A0B5152898950F00000B8E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 35A0B5172898950F00000B8E /* Localizable.strings */; }; 44 | 35A0B51B2898953100000B8E /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35A0B51A2898953100000B8E /* WelcomeView.swift */; }; 45 | 35A0B51D2898958200000B8E /* LocaleKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35A0B51C2898958200000B8E /* LocaleKeys.swift */; }; 46 | 35A0B520289895EC00000B8E /* HelloView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35A0B51F289895EC00000B8E /* HelloView.swift */; }; 47 | 35A0B522289896E200000B8E /* View+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35A0B521289896E200000B8E /* View+Style.swift */; }; 48 | 35C185012857FCCD00E15C42 /* MarketHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C185002857FCCD00E15C42 /* MarketHomeView.swift */; }; 49 | 35C185052857FD0D00E15C42 /* MarketItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C185042857FD0D00E15C42 /* MarketItem.swift */; }; 50 | 35C185072857FDE900E15C42 /* MarketViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C185062857FDE900E15C42 /* MarketViewModel.swift */; }; 51 | 35C18509285801D400E15C42 /* MarketDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C18508285801D400E15C42 /* MarketDetailView.swift */; }; 52 | 35C1850B285801ED00E15C42 /* MarketDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35C1850A285801ED00E15C42 /* MarketDetailViewModel.swift */; }; 53 | 35CE466027389A31002035E9 /* NavigationUsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35CE465F27389A31002035E9 /* NavigationUsers.swift */; }; 54 | 35CE466227389A53002035E9 /* NavigationUserModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35CE466127389A53002035E9 /* NavigationUserModel.swift */; }; 55 | 35CE466427389CFC002035E9 /* UserViewDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35CE466327389CFC002035E9 /* UserViewDetail.swift */; }; 56 | 35F77FC3272630CF00A925A9 /* ModelListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F77FC2272630CF00A925A9 /* ModelListView.swift */; }; 57 | 35F77FC5272630FD00A925A9 /* TweetModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F77FC4272630FD00A925A9 /* TweetModel.swift */; }; 58 | 35F77FC72726338B00A925A9 /* TweetCards.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F77FC62726338B00A925A9 /* TweetCards.swift */; }; 59 | /* End PBXBuildFile section */ 60 | 61 | /* Begin PBXFileReference section */ 62 | 350382D2281F6A46000A16F7 /* RandomFoxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomFoxView.swift; sourceTree = ""; }; 63 | 350382D4281F6C3F000A16F7 /* FoxModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoxModel.swift; sourceTree = ""; }; 64 | 350382D6281F6C79000A16F7 /* FoxService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoxService.swift; sourceTree = ""; }; 65 | 350382DC281F6F0E000A16F7 /* FoxViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoxViewModel.swift; sourceTree = ""; }; 66 | 350F8BAD2858045900193C2D /* Navigaton+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Navigaton+View.swift"; sourceTree = ""; }; 67 | 3518296E270A62840086818B /* CircleTextImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleTextImageView.swift; sourceTree = ""; }; 68 | 3556891F286A754800F37779 /* PropetyWrapperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropetyWrapperView.swift; sourceTree = ""; }; 69 | 35568921286A756200F37779 /* UserWrapperModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserWrapperModel.swift; sourceTree = ""; }; 70 | 35568923286A75AC00F37779 /* UpperCaseWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpperCaseWrapper.swift; sourceTree = ""; }; 71 | 35568925286A775600F37779 /* NumberCaseWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberCaseWrapper.swift; sourceTree = ""; }; 72 | 3568CDD2276FD6B500464155 /* CustomTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTabView.swift; sourceTree = ""; }; 73 | 3568CDD4276FD8F000464155 /* CustomTabIndex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTabIndex.swift; sourceTree = ""; }; 74 | 357039E827B339D800B2AE4D /* EnviromentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnviromentView.swift; sourceTree = ""; }; 75 | 357039EA27B33A9700B2AE4D /* Spacer+Constant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Spacer+Constant.swift"; sourceTree = ""; }; 76 | 357039EE27B33F1100B2AE4D /* DateControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateControlView.swift; sourceTree = ""; }; 77 | 3577D0CC28458AD600159ABA /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; 78 | 3577D0CE28458B0400159ABA /* UserService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserService.swift; sourceTree = ""; }; 79 | 3577D0D228458CCF00159ABA /* Logging+AFError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Logging+AFError.swift"; sourceTree = ""; }; 80 | 3577D0D728458EFC00159ABA /* UserViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserViewModel.swift; sourceTree = ""; }; 81 | 3577D0DB2845900800159ABA /* UserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserView.swift; sourceTree = ""; }; 82 | 357F7D7426D30FE2004182D6 /* SwiftUITutorials.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUITutorials.app; sourceTree = BUILT_PRODUCTS_DIR; }; 83 | 357F7D7726D30FE2004182D6 /* SwiftUITutorialsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUITutorialsApp.swift; sourceTree = ""; }; 84 | 357F7D7926D30FE2004182D6 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 85 | 357F7D7B26D30FE4004182D6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 86 | 357F7D7E26D30FE4004182D6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 87 | 357F7D8026D30FE4004182D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 88 | 3584539B27139F13006C3225 /* SampleListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleListView.swift; sourceTree = ""; }; 89 | 3596D82E288602C100B55654 /* TimerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerView.swift; sourceTree = ""; }; 90 | 3596D8302886072E00B55654 /* TextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEditingView.swift; sourceTree = ""; }; 91 | 3596D8322886085D00B55654 /* LabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelView.swift; sourceTree = ""; }; 92 | 3596D834288609BF00B55654 /* TabGestureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabGestureView.swift; sourceTree = ""; }; 93 | 35A0B5162898950F00000B8E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; 94 | 35A0B5182898951200000B8E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 95 | 35A0B51A2898953100000B8E /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; 96 | 35A0B51C2898958200000B8E /* LocaleKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleKeys.swift; sourceTree = ""; }; 97 | 35A0B51F289895EC00000B8E /* HelloView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelloView.swift; sourceTree = ""; }; 98 | 35A0B521289896E200000B8E /* View+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Style.swift"; sourceTree = ""; }; 99 | 35C185002857FCCD00E15C42 /* MarketHomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketHomeView.swift; sourceTree = ""; }; 100 | 35C185042857FD0D00E15C42 /* MarketItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketItem.swift; sourceTree = ""; }; 101 | 35C185062857FDE900E15C42 /* MarketViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketViewModel.swift; sourceTree = ""; }; 102 | 35C18508285801D400E15C42 /* MarketDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketDetailView.swift; sourceTree = ""; }; 103 | 35C1850A285801ED00E15C42 /* MarketDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketDetailViewModel.swift; sourceTree = ""; }; 104 | 35CE465F27389A31002035E9 /* NavigationUsers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationUsers.swift; sourceTree = ""; }; 105 | 35CE466127389A53002035E9 /* NavigationUserModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationUserModel.swift; sourceTree = ""; }; 106 | 35CE466327389CFC002035E9 /* UserViewDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserViewDetail.swift; sourceTree = ""; }; 107 | 35F77FC2272630CF00A925A9 /* ModelListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelListView.swift; sourceTree = ""; }; 108 | 35F77FC4272630FD00A925A9 /* TweetModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TweetModel.swift; sourceTree = ""; }; 109 | 35F77FC62726338B00A925A9 /* TweetCards.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TweetCards.swift; sourceTree = ""; }; 110 | /* End PBXFileReference section */ 111 | 112 | /* Begin PBXFrameworksBuildPhase section */ 113 | 357F7D7126D30FE2004182D6 /* Frameworks */ = { 114 | isa = PBXFrameworksBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 3518296B270A5FEB0086818B /* Kingfisher in Frameworks */, 118 | 350382E0281F70EF000A16F7 /* ActivityIndicatorView in Frameworks */, 119 | 3577D0D628458D5400159ABA /* Logging in Frameworks */, 120 | 350382DA281F6CE7000A16F7 /* Alamofire in Frameworks */, 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | /* End PBXFrameworksBuildPhase section */ 125 | 126 | /* Begin PBXGroup section */ 127 | 350382CD281F69B3000A16F7 /* FoxViewModel */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 350382D1281F69FB000A16F7 /* Model */, 131 | 350382D0281F69F0000A16F7 /* Service */, 132 | 350382CF281F69E7000A16F7 /* ViewModel */, 133 | 350382CE281F69D9000A16F7 /* View */, 134 | ); 135 | path = FoxViewModel; 136 | sourceTree = ""; 137 | }; 138 | 350382CE281F69D9000A16F7 /* View */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 350382D2281F6A46000A16F7 /* RandomFoxView.swift */, 142 | ); 143 | path = View; 144 | sourceTree = ""; 145 | }; 146 | 350382CF281F69E7000A16F7 /* ViewModel */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 350382DC281F6F0E000A16F7 /* FoxViewModel.swift */, 150 | ); 151 | path = ViewModel; 152 | sourceTree = ""; 153 | }; 154 | 350382D0281F69F0000A16F7 /* Service */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 350382D6281F6C79000A16F7 /* FoxService.swift */, 158 | ); 159 | path = Service; 160 | sourceTree = ""; 161 | }; 162 | 350382D1281F69FB000A16F7 /* Model */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 350382D4281F6C3F000A16F7 /* FoxModel.swift */, 166 | ); 167 | path = Model; 168 | sourceTree = ""; 169 | }; 170 | 3518296C270A624F0086818B /* View */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 3596D82D288602A500B55654 /* 19July */, 174 | 3518296D270A625C0086818B /* Circle */, 175 | ); 176 | path = View; 177 | sourceTree = ""; 178 | }; 179 | 3518296D270A625C0086818B /* Circle */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 3518296E270A62840086818B /* CircleTextImageView.swift */, 183 | ); 184 | path = Circle; 185 | sourceTree = ""; 186 | }; 187 | 3556891C286A751200F37779 /* PropertyWrapper */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 3556891F286A754800F37779 /* PropetyWrapperView.swift */, 191 | 35568921286A756200F37779 /* UserWrapperModel.swift */, 192 | 35568923286A75AC00F37779 /* UpperCaseWrapper.swift */, 193 | 35568925286A775600F37779 /* NumberCaseWrapper.swift */, 194 | ); 195 | path = PropertyWrapper; 196 | sourceTree = ""; 197 | }; 198 | 3568CDD1276FD6A600464155 /* CustomTabView */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | 3568CDD2276FD6B500464155 /* CustomTabView.swift */, 202 | 3568CDD4276FD8F000464155 /* CustomTabIndex.swift */, 203 | ); 204 | path = CustomTabView; 205 | sourceTree = ""; 206 | }; 207 | 357039E727B339A900B2AE4D /* Enıroment */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 357039E827B339D800B2AE4D /* EnviromentView.swift */, 211 | 357039EA27B33A9700B2AE4D /* Spacer+Constant.swift */, 212 | 357039EE27B33F1100B2AE4D /* DateControlView.swift */, 213 | ); 214 | path = "Enıroment"; 215 | sourceTree = ""; 216 | }; 217 | 3577D0C728458A7900159ABA /* ReqResViewModel */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 3577D0CB28458AAE00159ABA /* Model */, 221 | 3577D0CA28458AAB00159ABA /* View */, 222 | 3577D0C928458AA600159ABA /* Service */, 223 | 3577D0C828458A8A00159ABA /* ViewModel */, 224 | ); 225 | path = ReqResViewModel; 226 | sourceTree = ""; 227 | }; 228 | 3577D0C828458A8A00159ABA /* ViewModel */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 3577D0D728458EFC00159ABA /* UserViewModel.swift */, 232 | ); 233 | path = ViewModel; 234 | sourceTree = ""; 235 | }; 236 | 3577D0C928458AA600159ABA /* Service */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | 3577D0CE28458B0400159ABA /* UserService.swift */, 240 | ); 241 | path = Service; 242 | sourceTree = ""; 243 | }; 244 | 3577D0CA28458AAB00159ABA /* View */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | 3577D0DB2845900800159ABA /* UserView.swift */, 248 | ); 249 | path = View; 250 | sourceTree = ""; 251 | }; 252 | 3577D0CB28458AAE00159ABA /* Model */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | 3577D0CC28458AD600159ABA /* User.swift */, 256 | ); 257 | path = Model; 258 | sourceTree = ""; 259 | }; 260 | 3577D0D028458CB400159ABA /* Core */ = { 261 | isa = PBXGroup; 262 | children = ( 263 | 3577D0D128458CB900159ABA /* Extension */, 264 | ); 265 | path = Core; 266 | sourceTree = ""; 267 | }; 268 | 3577D0D128458CB900159ABA /* Extension */ = { 269 | isa = PBXGroup; 270 | children = ( 271 | 3577D0D228458CCF00159ABA /* Logging+AFError.swift */, 272 | 350F8BAD2858045900193C2D /* Navigaton+View.swift */, 273 | ); 274 | path = Extension; 275 | sourceTree = ""; 276 | }; 277 | 357F7D6B26D30FE2004182D6 = { 278 | isa = PBXGroup; 279 | children = ( 280 | 35A0B5172898950F00000B8E /* Localizable.strings */, 281 | 357F7D7626D30FE2004182D6 /* SwiftUITutorials */, 282 | 357F7D7526D30FE2004182D6 /* Products */, 283 | ); 284 | sourceTree = ""; 285 | }; 286 | 357F7D7526D30FE2004182D6 /* Products */ = { 287 | isa = PBXGroup; 288 | children = ( 289 | 357F7D7426D30FE2004182D6 /* SwiftUITutorials.app */, 290 | ); 291 | name = Products; 292 | sourceTree = ""; 293 | }; 294 | 357F7D7626D30FE2004182D6 /* SwiftUITutorials */ = { 295 | isa = PBXGroup; 296 | children = ( 297 | 35A0B51E289895D600000B8E /* ViewModifier */, 298 | 35A0B5192898952900000B8E /* Localizable */, 299 | 3577D0D028458CB400159ABA /* Core */, 300 | 3584539827139EEB006C3225 /* Features */, 301 | 3518296C270A624F0086818B /* View */, 302 | 357F7D7726D30FE2004182D6 /* SwiftUITutorialsApp.swift */, 303 | 357F7D7926D30FE2004182D6 /* ContentView.swift */, 304 | 357F7D7B26D30FE4004182D6 /* Assets.xcassets */, 305 | 357F7D8026D30FE4004182D6 /* Info.plist */, 306 | 357F7D7D26D30FE4004182D6 /* Preview Content */, 307 | ); 308 | path = SwiftUITutorials; 309 | sourceTree = ""; 310 | }; 311 | 357F7D7D26D30FE4004182D6 /* Preview Content */ = { 312 | isa = PBXGroup; 313 | children = ( 314 | 357F7D7E26D30FE4004182D6 /* Preview Assets.xcassets */, 315 | ); 316 | path = "Preview Content"; 317 | sourceTree = ""; 318 | }; 319 | 3584539827139EEB006C3225 /* Features */ = { 320 | isa = PBXGroup; 321 | children = ( 322 | 3556891C286A751200F37779 /* PropertyWrapper */, 323 | 35C184FD2857FCA300E15C42 /* Market */, 324 | 3577D0C728458A7900159ABA /* ReqResViewModel */, 325 | 350382CD281F69B3000A16F7 /* FoxViewModel */, 326 | 357039E727B339A900B2AE4D /* Enıroment */, 327 | 3568CDD1276FD6A600464155 /* CustomTabView */, 328 | 35CE465E27389A18002035E9 /* Navigation */, 329 | 35F77FC1272630C000A925A9 /* ModelList */, 330 | 3584539B27139F13006C3225 /* SampleListView.swift */, 331 | ); 332 | path = Features; 333 | sourceTree = ""; 334 | }; 335 | 3596D82D288602A500B55654 /* 19July */ = { 336 | isa = PBXGroup; 337 | children = ( 338 | 3596D82E288602C100B55654 /* TimerView.swift */, 339 | 3596D8302886072E00B55654 /* TextEditingView.swift */, 340 | 3596D8322886085D00B55654 /* LabelView.swift */, 341 | 3596D834288609BF00B55654 /* TabGestureView.swift */, 342 | ); 343 | path = 19July; 344 | sourceTree = ""; 345 | }; 346 | 35A0B5192898952900000B8E /* Localizable */ = { 347 | isa = PBXGroup; 348 | children = ( 349 | 35A0B51A2898953100000B8E /* WelcomeView.swift */, 350 | 35A0B51C2898958200000B8E /* LocaleKeys.swift */, 351 | ); 352 | path = Localizable; 353 | sourceTree = ""; 354 | }; 355 | 35A0B51E289895D600000B8E /* ViewModifier */ = { 356 | isa = PBXGroup; 357 | children = ( 358 | 35A0B51F289895EC00000B8E /* HelloView.swift */, 359 | 35A0B521289896E200000B8E /* View+Style.swift */, 360 | ); 361 | path = ViewModifier; 362 | sourceTree = ""; 363 | }; 364 | 35C184FD2857FCA300E15C42 /* Market */ = { 365 | isa = PBXGroup; 366 | children = ( 367 | 35C184FF2857FCB200E15C42 /* HomeDetail */, 368 | 35C184FE2857FCA900E15C42 /* Home */, 369 | ); 370 | path = Market; 371 | sourceTree = ""; 372 | }; 373 | 35C184FE2857FCA900E15C42 /* Home */ = { 374 | isa = PBXGroup; 375 | children = ( 376 | 35C185032857FCFF00E15C42 /* Model */, 377 | 35C185022857FCEA00E15C42 /* ViewModel */, 378 | 35C185002857FCCD00E15C42 /* MarketHomeView.swift */, 379 | ); 380 | path = Home; 381 | sourceTree = ""; 382 | }; 383 | 35C184FF2857FCB200E15C42 /* HomeDetail */ = { 384 | isa = PBXGroup; 385 | children = ( 386 | 35C18508285801D400E15C42 /* MarketDetailView.swift */, 387 | 35C1850A285801ED00E15C42 /* MarketDetailViewModel.swift */, 388 | ); 389 | path = HomeDetail; 390 | sourceTree = ""; 391 | }; 392 | 35C185022857FCEA00E15C42 /* ViewModel */ = { 393 | isa = PBXGroup; 394 | children = ( 395 | 35C185062857FDE900E15C42 /* MarketViewModel.swift */, 396 | ); 397 | path = ViewModel; 398 | sourceTree = ""; 399 | }; 400 | 35C185032857FCFF00E15C42 /* Model */ = { 401 | isa = PBXGroup; 402 | children = ( 403 | 35C185042857FD0D00E15C42 /* MarketItem.swift */, 404 | ); 405 | path = Model; 406 | sourceTree = ""; 407 | }; 408 | 35CE465E27389A18002035E9 /* Navigation */ = { 409 | isa = PBXGroup; 410 | children = ( 411 | 35CE465F27389A31002035E9 /* NavigationUsers.swift */, 412 | 35CE466127389A53002035E9 /* NavigationUserModel.swift */, 413 | 35CE466327389CFC002035E9 /* UserViewDetail.swift */, 414 | ); 415 | path = Navigation; 416 | sourceTree = ""; 417 | }; 418 | 35F77FC1272630C000A925A9 /* ModelList */ = { 419 | isa = PBXGroup; 420 | children = ( 421 | 35F77FC2272630CF00A925A9 /* ModelListView.swift */, 422 | 35F77FC4272630FD00A925A9 /* TweetModel.swift */, 423 | 35F77FC62726338B00A925A9 /* TweetCards.swift */, 424 | ); 425 | path = ModelList; 426 | sourceTree = ""; 427 | }; 428 | /* End PBXGroup section */ 429 | 430 | /* Begin PBXNativeTarget section */ 431 | 357F7D7326D30FE2004182D6 /* SwiftUITutorials */ = { 432 | isa = PBXNativeTarget; 433 | buildConfigurationList = 357F7D8326D30FE4004182D6 /* Build configuration list for PBXNativeTarget "SwiftUITutorials" */; 434 | buildPhases = ( 435 | 357F7D7026D30FE2004182D6 /* Sources */, 436 | 357F7D7126D30FE2004182D6 /* Frameworks */, 437 | 357F7D7226D30FE2004182D6 /* Resources */, 438 | ); 439 | buildRules = ( 440 | ); 441 | dependencies = ( 442 | ); 443 | name = SwiftUITutorials; 444 | packageProductDependencies = ( 445 | 3518296A270A5FEB0086818B /* Kingfisher */, 446 | 350382D9281F6CE7000A16F7 /* Alamofire */, 447 | 350382DF281F70EF000A16F7 /* ActivityIndicatorView */, 448 | 3577D0D528458D5400159ABA /* Logging */, 449 | ); 450 | productName = SwiftUITutorials; 451 | productReference = 357F7D7426D30FE2004182D6 /* SwiftUITutorials.app */; 452 | productType = "com.apple.product-type.application"; 453 | }; 454 | /* End PBXNativeTarget section */ 455 | 456 | /* Begin PBXProject section */ 457 | 357F7D6C26D30FE2004182D6 /* Project object */ = { 458 | isa = PBXProject; 459 | attributes = { 460 | LastSwiftUpdateCheck = 1250; 461 | LastUpgradeCheck = 1250; 462 | TargetAttributes = { 463 | 357F7D7326D30FE2004182D6 = { 464 | CreatedOnToolsVersion = 12.5.1; 465 | }; 466 | }; 467 | }; 468 | buildConfigurationList = 357F7D6F26D30FE2004182D6 /* Build configuration list for PBXProject "SwiftUITutorials" */; 469 | compatibilityVersion = "Xcode 9.3"; 470 | developmentRegion = en; 471 | hasScannedForEncodings = 0; 472 | knownRegions = ( 473 | en, 474 | Base, 475 | tr, 476 | ); 477 | mainGroup = 357F7D6B26D30FE2004182D6; 478 | packageReferences = ( 479 | 35182969270A5FEB0086818B /* XCRemoteSwiftPackageReference "Kingfisher" */, 480 | 350382D8281F6CE7000A16F7 /* XCRemoteSwiftPackageReference "Alamofire" */, 481 | 350382DE281F70EF000A16F7 /* XCRemoteSwiftPackageReference "ActivityIndicatorView" */, 482 | 3577D0D428458D5300159ABA /* XCRemoteSwiftPackageReference "swift-log" */, 483 | ); 484 | productRefGroup = 357F7D7526D30FE2004182D6 /* Products */; 485 | projectDirPath = ""; 486 | projectRoot = ""; 487 | targets = ( 488 | 357F7D7326D30FE2004182D6 /* SwiftUITutorials */, 489 | ); 490 | }; 491 | /* End PBXProject section */ 492 | 493 | /* Begin PBXResourcesBuildPhase section */ 494 | 357F7D7226D30FE2004182D6 /* Resources */ = { 495 | isa = PBXResourcesBuildPhase; 496 | buildActionMask = 2147483647; 497 | files = ( 498 | 357F7D7F26D30FE4004182D6 /* Preview Assets.xcassets in Resources */, 499 | 35A0B5152898950F00000B8E /* Localizable.strings in Resources */, 500 | 357F7D7C26D30FE4004182D6 /* Assets.xcassets in Resources */, 501 | ); 502 | runOnlyForDeploymentPostprocessing = 0; 503 | }; 504 | /* End PBXResourcesBuildPhase section */ 505 | 506 | /* Begin PBXSourcesBuildPhase section */ 507 | 357F7D7026D30FE2004182D6 /* Sources */ = { 508 | isa = PBXSourcesBuildPhase; 509 | buildActionMask = 2147483647; 510 | files = ( 511 | 3596D8312886072E00B55654 /* TextEditingView.swift in Sources */, 512 | 3596D82F288602C100B55654 /* TimerView.swift in Sources */, 513 | 35A0B522289896E200000B8E /* View+Style.swift in Sources */, 514 | 35C185072857FDE900E15C42 /* MarketViewModel.swift in Sources */, 515 | 35CE466427389CFC002035E9 /* UserViewDetail.swift in Sources */, 516 | 35568922286A756200F37779 /* UserWrapperModel.swift in Sources */, 517 | 350382D5281F6C3F000A16F7 /* FoxModel.swift in Sources */, 518 | 357039EB27B33A9700B2AE4D /* Spacer+Constant.swift in Sources */, 519 | 35A0B51B2898953100000B8E /* WelcomeView.swift in Sources */, 520 | 357039EF27B33F1100B2AE4D /* DateControlView.swift in Sources */, 521 | 3596D8332886085D00B55654 /* LabelView.swift in Sources */, 522 | 3584539C27139F13006C3225 /* SampleListView.swift in Sources */, 523 | 3577D0D328458CCF00159ABA /* Logging+AFError.swift in Sources */, 524 | 35568920286A754800F37779 /* PropetyWrapperView.swift in Sources */, 525 | 357F7D7A26D30FE2004182D6 /* ContentView.swift in Sources */, 526 | 35568926286A775600F37779 /* NumberCaseWrapper.swift in Sources */, 527 | 35CE466027389A31002035E9 /* NavigationUsers.swift in Sources */, 528 | 3518296F270A62840086818B /* CircleTextImageView.swift in Sources */, 529 | 3577D0CD28458AD600159ABA /* User.swift in Sources */, 530 | 35C18509285801D400E15C42 /* MarketDetailView.swift in Sources */, 531 | 3577D0D828458EFC00159ABA /* UserViewModel.swift in Sources */, 532 | 350382D3281F6A46000A16F7 /* RandomFoxView.swift in Sources */, 533 | 35C185012857FCCD00E15C42 /* MarketHomeView.swift in Sources */, 534 | 350382D7281F6C79000A16F7 /* FoxService.swift in Sources */, 535 | 35F77FC5272630FD00A925A9 /* TweetModel.swift in Sources */, 536 | 35F77FC72726338B00A925A9 /* TweetCards.swift in Sources */, 537 | 3596D835288609BF00B55654 /* TabGestureView.swift in Sources */, 538 | 35C1850B285801ED00E15C42 /* MarketDetailViewModel.swift in Sources */, 539 | 350F8BAE2858045A00193C2D /* Navigaton+View.swift in Sources */, 540 | 3568CDD3276FD6B500464155 /* CustomTabView.swift in Sources */, 541 | 3577D0CF28458B0400159ABA /* UserService.swift in Sources */, 542 | 35568924286A75AC00F37779 /* UpperCaseWrapper.swift in Sources */, 543 | 35C185052857FD0D00E15C42 /* MarketItem.swift in Sources */, 544 | 357F7D7826D30FE2004182D6 /* SwiftUITutorialsApp.swift in Sources */, 545 | 350382DD281F6F0E000A16F7 /* FoxViewModel.swift in Sources */, 546 | 3577D0DC2845900800159ABA /* UserView.swift in Sources */, 547 | 3568CDD5276FD8F100464155 /* CustomTabIndex.swift in Sources */, 548 | 357039E927B339D800B2AE4D /* EnviromentView.swift in Sources */, 549 | 35CE466227389A53002035E9 /* NavigationUserModel.swift in Sources */, 550 | 35A0B520289895EC00000B8E /* HelloView.swift in Sources */, 551 | 35F77FC3272630CF00A925A9 /* ModelListView.swift in Sources */, 552 | 35A0B51D2898958200000B8E /* LocaleKeys.swift in Sources */, 553 | ); 554 | runOnlyForDeploymentPostprocessing = 0; 555 | }; 556 | /* End PBXSourcesBuildPhase section */ 557 | 558 | /* Begin PBXVariantGroup section */ 559 | 35A0B5172898950F00000B8E /* Localizable.strings */ = { 560 | isa = PBXVariantGroup; 561 | children = ( 562 | 35A0B5162898950F00000B8E /* tr */, 563 | 35A0B5182898951200000B8E /* en */, 564 | ); 565 | name = Localizable.strings; 566 | sourceTree = ""; 567 | }; 568 | /* End PBXVariantGroup section */ 569 | 570 | /* Begin XCBuildConfiguration section */ 571 | 357F7D8126D30FE4004182D6 /* Debug */ = { 572 | isa = XCBuildConfiguration; 573 | buildSettings = { 574 | ALWAYS_SEARCH_USER_PATHS = NO; 575 | CLANG_ANALYZER_NONNULL = YES; 576 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 577 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 578 | CLANG_CXX_LIBRARY = "libc++"; 579 | CLANG_ENABLE_MODULES = YES; 580 | CLANG_ENABLE_OBJC_ARC = YES; 581 | CLANG_ENABLE_OBJC_WEAK = YES; 582 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 583 | CLANG_WARN_BOOL_CONVERSION = YES; 584 | CLANG_WARN_COMMA = YES; 585 | CLANG_WARN_CONSTANT_CONVERSION = YES; 586 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 587 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 588 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 589 | CLANG_WARN_EMPTY_BODY = YES; 590 | CLANG_WARN_ENUM_CONVERSION = YES; 591 | CLANG_WARN_INFINITE_RECURSION = YES; 592 | CLANG_WARN_INT_CONVERSION = YES; 593 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 594 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 595 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 596 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 597 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 598 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 599 | CLANG_WARN_STRICT_PROTOTYPES = YES; 600 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 601 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 602 | CLANG_WARN_UNREACHABLE_CODE = YES; 603 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 604 | COPY_PHASE_STRIP = NO; 605 | DEBUG_INFORMATION_FORMAT = dwarf; 606 | ENABLE_STRICT_OBJC_MSGSEND = YES; 607 | ENABLE_TESTABILITY = YES; 608 | GCC_C_LANGUAGE_STANDARD = gnu11; 609 | GCC_DYNAMIC_NO_PIC = NO; 610 | GCC_NO_COMMON_BLOCKS = YES; 611 | GCC_OPTIMIZATION_LEVEL = 0; 612 | GCC_PREPROCESSOR_DEFINITIONS = ( 613 | "DEBUG=1", 614 | "$(inherited)", 615 | ); 616 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 617 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 618 | GCC_WARN_UNDECLARED_SELECTOR = YES; 619 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 620 | GCC_WARN_UNUSED_FUNCTION = YES; 621 | GCC_WARN_UNUSED_VARIABLE = YES; 622 | IPHONEOS_DEPLOYMENT_TARGET = 14.5; 623 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 624 | MTL_FAST_MATH = YES; 625 | ONLY_ACTIVE_ARCH = YES; 626 | SDKROOT = iphoneos; 627 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 628 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 629 | }; 630 | name = Debug; 631 | }; 632 | 357F7D8226D30FE4004182D6 /* Release */ = { 633 | isa = XCBuildConfiguration; 634 | buildSettings = { 635 | ALWAYS_SEARCH_USER_PATHS = NO; 636 | CLANG_ANALYZER_NONNULL = YES; 637 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 638 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 639 | CLANG_CXX_LIBRARY = "libc++"; 640 | CLANG_ENABLE_MODULES = YES; 641 | CLANG_ENABLE_OBJC_ARC = YES; 642 | CLANG_ENABLE_OBJC_WEAK = YES; 643 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 644 | CLANG_WARN_BOOL_CONVERSION = YES; 645 | CLANG_WARN_COMMA = YES; 646 | CLANG_WARN_CONSTANT_CONVERSION = YES; 647 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 648 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 649 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 650 | CLANG_WARN_EMPTY_BODY = YES; 651 | CLANG_WARN_ENUM_CONVERSION = YES; 652 | CLANG_WARN_INFINITE_RECURSION = YES; 653 | CLANG_WARN_INT_CONVERSION = YES; 654 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 655 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 656 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 657 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 658 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 659 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 660 | CLANG_WARN_STRICT_PROTOTYPES = YES; 661 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 662 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 663 | CLANG_WARN_UNREACHABLE_CODE = YES; 664 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 665 | COPY_PHASE_STRIP = NO; 666 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 667 | ENABLE_NS_ASSERTIONS = NO; 668 | ENABLE_STRICT_OBJC_MSGSEND = YES; 669 | GCC_C_LANGUAGE_STANDARD = gnu11; 670 | GCC_NO_COMMON_BLOCKS = YES; 671 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 672 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 673 | GCC_WARN_UNDECLARED_SELECTOR = YES; 674 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 675 | GCC_WARN_UNUSED_FUNCTION = YES; 676 | GCC_WARN_UNUSED_VARIABLE = YES; 677 | IPHONEOS_DEPLOYMENT_TARGET = 14.5; 678 | MTL_ENABLE_DEBUG_INFO = NO; 679 | MTL_FAST_MATH = YES; 680 | SDKROOT = iphoneos; 681 | SWIFT_COMPILATION_MODE = wholemodule; 682 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 683 | VALIDATE_PRODUCT = YES; 684 | }; 685 | name = Release; 686 | }; 687 | 357F7D8426D30FE4004182D6 /* Debug */ = { 688 | isa = XCBuildConfiguration; 689 | buildSettings = { 690 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 691 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 692 | CODE_SIGN_STYLE = Automatic; 693 | DEVELOPMENT_ASSET_PATHS = "\"SwiftUITutorials/Preview Content\""; 694 | ENABLE_PREVIEWS = YES; 695 | INFOPLIST_FILE = SwiftUITutorials/Info.plist; 696 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 697 | LD_RUNPATH_SEARCH_PATHS = ( 698 | "$(inherited)", 699 | "@executable_path/Frameworks", 700 | ); 701 | PRODUCT_BUNDLE_IDENTIFIER = com.vb10.SwiftUITutorials; 702 | PRODUCT_NAME = "$(TARGET_NAME)"; 703 | SWIFT_VERSION = 5.0; 704 | TARGETED_DEVICE_FAMILY = "1,2"; 705 | }; 706 | name = Debug; 707 | }; 708 | 357F7D8526D30FE4004182D6 /* Release */ = { 709 | isa = XCBuildConfiguration; 710 | buildSettings = { 711 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 712 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 713 | CODE_SIGN_STYLE = Automatic; 714 | DEVELOPMENT_ASSET_PATHS = "\"SwiftUITutorials/Preview Content\""; 715 | ENABLE_PREVIEWS = YES; 716 | INFOPLIST_FILE = SwiftUITutorials/Info.plist; 717 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 718 | LD_RUNPATH_SEARCH_PATHS = ( 719 | "$(inherited)", 720 | "@executable_path/Frameworks", 721 | ); 722 | PRODUCT_BUNDLE_IDENTIFIER = com.vb10.SwiftUITutorials; 723 | PRODUCT_NAME = "$(TARGET_NAME)"; 724 | SWIFT_VERSION = 5.0; 725 | TARGETED_DEVICE_FAMILY = "1,2"; 726 | }; 727 | name = Release; 728 | }; 729 | /* End XCBuildConfiguration section */ 730 | 731 | /* Begin XCConfigurationList section */ 732 | 357F7D6F26D30FE2004182D6 /* Build configuration list for PBXProject "SwiftUITutorials" */ = { 733 | isa = XCConfigurationList; 734 | buildConfigurations = ( 735 | 357F7D8126D30FE4004182D6 /* Debug */, 736 | 357F7D8226D30FE4004182D6 /* Release */, 737 | ); 738 | defaultConfigurationIsVisible = 0; 739 | defaultConfigurationName = Release; 740 | }; 741 | 357F7D8326D30FE4004182D6 /* Build configuration list for PBXNativeTarget "SwiftUITutorials" */ = { 742 | isa = XCConfigurationList; 743 | buildConfigurations = ( 744 | 357F7D8426D30FE4004182D6 /* Debug */, 745 | 357F7D8526D30FE4004182D6 /* Release */, 746 | ); 747 | defaultConfigurationIsVisible = 0; 748 | defaultConfigurationName = Release; 749 | }; 750 | /* End XCConfigurationList section */ 751 | 752 | /* Begin XCRemoteSwiftPackageReference section */ 753 | 350382D8281F6CE7000A16F7 /* XCRemoteSwiftPackageReference "Alamofire" */ = { 754 | isa = XCRemoteSwiftPackageReference; 755 | repositoryURL = "https://github.com/Alamofire/Alamofire.git"; 756 | requirement = { 757 | branch = master; 758 | kind = branch; 759 | }; 760 | }; 761 | 350382DE281F70EF000A16F7 /* XCRemoteSwiftPackageReference "ActivityIndicatorView" */ = { 762 | isa = XCRemoteSwiftPackageReference; 763 | repositoryURL = "https://github.com/exyte/ActivityIndicatorView.git"; 764 | requirement = { 765 | branch = master; 766 | kind = branch; 767 | }; 768 | }; 769 | 35182969270A5FEB0086818B /* XCRemoteSwiftPackageReference "Kingfisher" */ = { 770 | isa = XCRemoteSwiftPackageReference; 771 | repositoryURL = "https://github.com/onevcat/Kingfisher.git"; 772 | requirement = { 773 | kind = upToNextMajorVersion; 774 | minimumVersion = 7.0.0; 775 | }; 776 | }; 777 | 3577D0D428458D5300159ABA /* XCRemoteSwiftPackageReference "swift-log" */ = { 778 | isa = XCRemoteSwiftPackageReference; 779 | repositoryURL = "https://github.com/apple/swift-log.git"; 780 | requirement = { 781 | kind = upToNextMajorVersion; 782 | minimumVersion = 1.0.0; 783 | }; 784 | }; 785 | /* End XCRemoteSwiftPackageReference section */ 786 | 787 | /* Begin XCSwiftPackageProductDependency section */ 788 | 350382D9281F6CE7000A16F7 /* Alamofire */ = { 789 | isa = XCSwiftPackageProductDependency; 790 | package = 350382D8281F6CE7000A16F7 /* XCRemoteSwiftPackageReference "Alamofire" */; 791 | productName = Alamofire; 792 | }; 793 | 350382DF281F70EF000A16F7 /* ActivityIndicatorView */ = { 794 | isa = XCSwiftPackageProductDependency; 795 | package = 350382DE281F70EF000A16F7 /* XCRemoteSwiftPackageReference "ActivityIndicatorView" */; 796 | productName = ActivityIndicatorView; 797 | }; 798 | 3518296A270A5FEB0086818B /* Kingfisher */ = { 799 | isa = XCSwiftPackageProductDependency; 800 | package = 35182969270A5FEB0086818B /* XCRemoteSwiftPackageReference "Kingfisher" */; 801 | productName = Kingfisher; 802 | }; 803 | 3577D0D528458D5400159ABA /* Logging */ = { 804 | isa = XCSwiftPackageProductDependency; 805 | package = 3577D0D428458D5300159ABA /* XCRemoteSwiftPackageReference "swift-log" */; 806 | productName = Logging; 807 | }; 808 | /* End XCSwiftPackageProductDependency section */ 809 | }; 810 | rootObject = 357F7D6C26D30FE2004182D6 /* Project object */; 811 | } 812 | -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "activityindicatorview", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/exyte/ActivityIndicatorView.git", 7 | "state" : { 8 | "branch" : "master", 9 | "revision" : "0fb57e69b6130b4beb8ba49eaafe13563f2f6bd6" 10 | } 11 | }, 12 | { 13 | "identity" : "alamofire", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/Alamofire/Alamofire.git", 16 | "state" : { 17 | "branch" : "master", 18 | "revision" : "f7e169cd9c5e6b1a9d7403fc526a635fad0a787a" 19 | } 20 | }, 21 | { 22 | "identity" : "kingfisher", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/onevcat/Kingfisher.git", 25 | "state" : { 26 | "revision" : "8c65ddf756c633d01d9ae01092bf72f0c66dfc60", 27 | "version" : "7.0.0" 28 | } 29 | }, 30 | { 31 | "identity" : "swift-log", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/apple/swift-log.git", 34 | "state" : { 35 | "revision" : "5d66f7ba25daf4f94100e7022febf3c75e37a6c7", 36 | "version" : "1.4.2" 37 | } 38 | } 39 | ], 40 | "version" : 2 41 | } 42 | -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/project.xcworkspace/xcuserdata/vb.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/SwiftUITutorials/f2a174d11a40207b546de56e248485e2fe906fea/SwiftUITutorials.xcodeproj/project.xcworkspace/xcuserdata/vb.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/xcshareddata/xcschemes/SwiftUITutorials.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/xcuserdata/vb.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 25 | 37 | 38 | 39 | 41 | 53 | 54 | 55 | 57 | 69 | 70 | 71 | 73 | 85 | 86 | 87 | 89 | 101 | 102 | 103 | 105 | 117 | 118 | 119 | 121 | 133 | 134 | 135 | 137 | 149 | 150 | 151 | 153 | 165 | 166 | 167 | 169 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /SwiftUITutorials.xcodeproj/xcuserdata/vb.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftUITutorials.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "scale" : "3x" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/color_random.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.176", 9 | "green" : "0.612", 10 | "red" : "0.334" 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" : "1.000", 27 | "green" : "0.000", 28 | "red" : "1.000" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/snnm.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "snnm.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SwiftUITutorials/Assets.xcassets/snnm.imageset/snnm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/SwiftUITutorials/f2a174d11a40207b546de56e248485e2fe906fea/SwiftUITutorials/Assets.xcassets/snnm.imageset/snnm.png -------------------------------------------------------------------------------- /SwiftUITutorials/Basket/BasketDetailViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BasketDetailViewModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BasketDetailViewModel: View { 11 | var body: some View { 12 | Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) 13 | } 14 | } 15 | 16 | struct BasketDetailViewModel_Previews: PreviewProvider { 17 | static var previews: some View { 18 | BasketDetailViewModel() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SwiftUITutorials/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 23.08.2021. 6 | // 7 | 8 | import SwiftUI 9 | import Kingfisher 10 | 11 | 12 | struct IconFieldView: View { 13 | 14 | var iconName: String = "hello" 15 | @State var textFieldValue: String = "" 16 | 17 | var body: some View { 18 | VStack { 19 | TextField("Placeholder", text: $textFieldValue) 20 | Text(textFieldValue) 21 | .bold() 22 | .font(.largeTitle) 23 | 24 | Image(systemName: textFieldValue.lowercased()).frame(width: 100, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 25 | 26 | } 27 | } 28 | 29 | } 30 | 31 | 32 | struct ContentView: View { 33 | 34 | private let imageUrl: String = "https://picsum.photos/id/237/200/300" 35 | 36 | 37 | var body: some View { 38 | CircleTextImageView(title: "Kabus", imageUrl: imageUrl).frame(width: 200, height: 200, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 39 | } 40 | 41 | 42 | 43 | 44 | 45 | // Lesson 5 46 | fileprivate func groupViews() -> some View { 47 | return VStack { 48 | 49 | Group { 50 | // MARK: Login View 51 | // TODO: Fix user name! 52 | VStack { 53 | Text("Hello") 54 | .accentColor(/*@START_MENU_TOKEN@*/.blue/*@END_MENU_TOKEN@*/) 55 | .font(/*@START_MENU_TOKEN@*/.callout/*@END_MENU_TOKEN@*/) 56 | }.frame(width: 200, height: 200, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).background(Color("color_random") 57 | .shadow(radius: /*@START_MENU_TOKEN@*/10/*@END_MENU_TOKEN@*/)) 58 | } 59 | Group { 60 | // MARK: Register View 61 | VStack { 62 | Image(systemName: "moon.fill").foregroundColor(.red) 63 | Text("Hello2") 64 | .foregroundColor(/*@START_MENU_TOKEN@*/.blue/*@END_MENU_TOKEN@*/) 65 | .opacity(/*@START_MENU_TOKEN@*/0.8/*@END_MENU_TOKEN@*/) 66 | } 67 | } 68 | } 69 | } 70 | 71 | 72 | fileprivate func demoView() -> some View { 73 | return VStack(alignment: .center) { 74 | Rectangle().frame(width: 100, height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 75 | Circle().foregroundColor(.red).frame(height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 76 | Text("Sampole1") 77 | Text("Sampole2") 78 | Text("Sampole3") 79 | Spacer() 80 | HStack() { 81 | RoundedRectangle(cornerRadius: /*@START_MENU_TOKEN@*/25.0/*@END_MENU_TOKEN@*/).frame(height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/) 82 | ZStack { 83 | Circle() 84 | Text("hello").font(.largeTitle).fontWeight(.heavy).foregroundColor(Color(red: 1.0, green: 0.0, blue: 0.0)) 85 | }.frame(height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 86 | 87 | }.frame(height: 500, alignment: Alignment.top) 88 | } 89 | } 90 | 91 | fileprivate func sampleHorizontalView() -> some View { 92 | return HStack { 93 | Spacer().frame(width: 100, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 94 | Text("@vb10") 95 | .padding() 96 | Text("@vb10") 97 | .padding() 98 | Text("@vb10") 99 | .padding() 100 | Text("@vb10") 101 | .padding() 102 | Color.red 103 | Spacer().frame(width: 100, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 104 | } 105 | } 106 | 107 | fileprivate func sampleVerticalView() -> some View { 108 | return VStack { 109 | Spacer().frame(width: 100, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 110 | Text("@vb10") 111 | .padding() 112 | Text("@vb10") 113 | .padding() 114 | Text("@vb10") 115 | .padding() 116 | Text("@vb10") 117 | .padding() 118 | Color.red 119 | Spacer().frame(width: 100, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 120 | } 121 | } 122 | 123 | fileprivate func sampleStackView() -> some View { 124 | return ZStack(alignment: Alignment.bottom) { 125 | Color.red 126 | Spacer().frame(width: 100, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 127 | Text("@vb10") 128 | .padding() 129 | Text("@vb10") 130 | .padding() 131 | Text("@v") 132 | .padding() 133 | Spacer().frame(width: 100, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 134 | } 135 | } 136 | } 137 | 138 | 139 | struct ContentView_Previews: PreviewProvider { 140 | static var previews: some View { 141 | EnviromentView() 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /SwiftUITutorials/Core/Extension/Logging+AFError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Logging_AFError.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 31.05.2022. 6 | // 7 | 8 | import Foundation 9 | import Alamofire 10 | import Logging 11 | 12 | extension AFError { 13 | private static let logger = Logger(label: "") 14 | 15 | func showError() { 16 | AFError.logger.error("\(errorDescription?.description)") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SwiftUITutorials/Core/Extension/Navigaton+View.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Navigaton+View.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | extension View { 12 | 13 | func dismiss() { 14 | @Environment(\.presentationMode) var presentationMode: Binding 15 | presentationMode.wrappedValue.dismiss() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/SwiftUITutorials/f2a174d11a40207b546de56e248485e2fe906fea/SwiftUITutorials/Features/.DS_Store -------------------------------------------------------------------------------- /SwiftUITutorials/Features/CustomTabView/CustomTabIndex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomTabIndex.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 20.12.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | enum CustomTabs: Int { 11 | case home = 0 12 | case heart = 1 13 | } 14 | 15 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/CustomTabView/CustomTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomTabView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 20.12.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CustomTabView: View { 11 | 12 | @State private var selectedIndex = CustomTabs.home 13 | 14 | var body: some View { 15 | VStack { 16 | Button("Reset") { 17 | selectedIndex = CustomTabs.home 18 | } 19 | TabView(selection: $selectedIndex) { 20 | HeartView().tabItem { 21 | Image(systemName: "heart") 22 | Text("Tab Label 1") }.tag(CustomTabs.home) 23 | 24 | StarView().tabItem { 25 | Image(systemName: "star") 26 | if selectedIndex == CustomTabs.heart { 27 | Text("Tab Label 2") 28 | } 29 | }.tag(CustomTabs.heart) 30 | }.accentColor(.red) 31 | } 32 | } 33 | } 34 | 35 | 36 | struct CustomTabView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | CustomTabView() 39 | } 40 | } 41 | 42 | struct StarView: View { 43 | var body: some View { 44 | Text("Tab Content 2") 45 | } 46 | } 47 | 48 | struct HeartView: View { 49 | @State private var fruits = [ 50 | "Apple", 51 | "Banana", 52 | "Papaya", 53 | "Mango" 54 | ] 55 | 56 | var body: some View { 57 | NavigationView{ 58 | VStack { 59 | NavigationLink(destination: Text("sample")) { 60 | Label("Lightning", systemImage: "bolt.fill") 61 | } 62 | 63 | List { 64 | ForEach( 65 | fruits, 66 | id: \.self 67 | ) { fruit in 68 | Text(fruit) 69 | } 70 | // .onDelete { self.deleteFruit(at :$0) } 71 | // .onMove { self.moveFruit(from: $0, to: $1) } 72 | } 73 | .navigationTitle("Fruits") 74 | .toolbar { EditButton() } 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Enıroment/DateControlView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DateControlView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 9.02.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct DateControlView: View { 11 | @EnvironmentObject var userController: UserController 12 | 13 | var body: some View { 14 | Text(userController.currentDate.timeIntervalSince1970.description) 15 | Button("Date Reset") { 16 | if #available(iOS 15, *) { 17 | userController.currentDate = Date.now 18 | } else { 19 | // Fallback on earlier versions 20 | } 21 | } 22 | } 23 | } 24 | 25 | struct DateControlView_Previews: PreviewProvider { 26 | static var previews: some View { 27 | DateControlView() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Enıroment/EnviromentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnviromentView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 9.02.2022. 6 | // 7 | 8 | import SwiftUI 9 | //EnvironmentValues 10 | struct EnviromentView: View { 11 | @Environment(\.horizontalSizeClass) var verticalSize 12 | @StateObject var userController = UserController() 13 | 14 | var body: some View { 15 | NavigationView { 16 | VStack { 17 | Text(userController.currentDate.description) 18 | HStack { 19 | verticalSize == .regular ? Spacer.minVerticalHigh : Spacer.minVertical 20 | DatePicker(selection: $userController.currentDate, label: { Text("Date") }) 21 | verticalSize == .regular ? Spacer.minVerticalHigh : Spacer.minVertical 22 | 23 | } 24 | 25 | NavigationLink { 26 | DateControlView() 27 | } label: { 28 | Text("Normal View") 29 | } 30 | 31 | } 32 | }.environmentObject(userController) 33 | } 34 | } 35 | 36 | class UserController: ObservableObject { 37 | @Published var currentDate: Date = Date() 38 | } 39 | 40 | struct EnviromentView_Previews: PreviewProvider { 41 | static var previews: some View { 42 | Group { 43 | EnviromentView() 44 | if #available(iOS 15.0, *) { 45 | EnviromentView() 46 | .previewInterfaceOrientation(.landscapeLeft) 47 | } else { 48 | // Fallback on earlier versions 49 | } 50 | } 51 | } 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Enıroment/Spacer+Constant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Spacer+Constant.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 9.02.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension Spacer { 11 | 12 | static let minVertical = Spacer(minLength: 20) 13 | static let minVerticalHigh = Spacer(minLength: 40) 14 | } 15 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/FoxViewModel/Model/FoxModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FoxModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.05.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - FoxModel 11 | struct FoxModel: Codable { 12 | let image: String? 13 | let link: String? 14 | } 15 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/FoxViewModel/Service/FoxService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FoxService.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.05.2022. 6 | // 7 | 8 | import Foundation 9 | import Alamofire 10 | 11 | protocol IFoxService { 12 | 13 | func fetchItem(path: FoxPaths, onSuccess: @escaping (FoxModel, Bool) -> Void) 14 | } 15 | 16 | class FoxService: IFoxService { 17 | private let baseUrl: String = "https://randomfox.ca/" 18 | 19 | func fetchItem(path: FoxPaths, onSuccess: @escaping (FoxModel, Bool) -> Void) { 20 | AF.request(baseUrl + path.rawValue).responseDecodable(of: FoxModel.self, completionHandler: { response in 21 | guard let value = response.value else { return } 22 | onSuccess(value, true) 23 | }) 24 | } 25 | } 26 | 27 | 28 | enum FoxPaths: String { 29 | case floof = "floof" 30 | } 31 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/FoxViewModel/View/RandomFoxView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RandomFoxView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.05.2022. 6 | // 7 | 8 | import SwiftUI 9 | import Kingfisher 10 | import ActivityIndicatorView 11 | 12 | struct RandomFoxView: View { 13 | private let title: String = "My fox" 14 | @StateObject private var foxViewModel: FoxViewModel = FoxViewModel(service: FoxService()) 15 | 16 | 17 | var body: some View { 18 | VStack { 19 | HStack { 20 | Text(title) 21 | .font(.largeTitle) 22 | Spacer() 23 | Button("Refresh") { 24 | foxViewModel.refreshView() 25 | } 26 | }.padding(.all) 27 | 28 | if foxViewModel.isCompleted ?? false { 29 | ExtractedView(imageUrl: foxViewModel.fox?.image) 30 | } else { 31 | LoadingView() 32 | } 33 | 34 | Spacer() 35 | } 36 | } 37 | } 38 | 39 | struct RandomFoxView_Previews: PreviewProvider { 40 | static var previews: some View { 41 | RandomFoxView() 42 | } 43 | } 44 | 45 | 46 | struct LoadingView: View { 47 | 48 | var body: some View { 49 | VStack { 50 | ActivityIndicatorView(isVisible: .constant(true), type: .growingCircle).frame(width: 50, height: 50, alignment: .center) 51 | } 52 | } 53 | 54 | } 55 | 56 | struct ExtractedView: View { 57 | let imageUrl: String? 58 | var body: some View { 59 | GeometryReader { geometry in 60 | KFImage(URL(string: imageUrl ?? "")) 61 | .resizable() 62 | .frame(height: geometry.size.height * 0.4, alignment: .center) 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/FoxViewModel/ViewModel/FoxViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FoxViewModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.05.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | class FoxViewModel: ObservableObject { 11 | init(service: IFoxService) { 12 | self.service = service 13 | fetchFox() 14 | } 15 | 16 | @Published var fox: FoxModel? 17 | @Published var isCompleted: Bool? 18 | private let service: IFoxService 19 | 20 | 21 | private func fetchFox() { 22 | service.fetchItem(path: .floof) { (data, isComplete) in 23 | self.isCompleted = isComplete 24 | self.fox = data 25 | } 26 | } 27 | 28 | func refreshView() { 29 | isCompleted = false 30 | fetchFox() 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Market/Home/MarketHomeView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MarketHomeView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MarketHomeView: View { 11 | @StateObject private var marketViewModel = MarketViewModel() 12 | 13 | var body: some View { 14 | NavigationView { 15 | VStack { 16 | List(marketViewModel.items) { item in 17 | Text(item.name) 18 | } 19 | NavigationLink(destination: MarketDetailView()) { 20 | Text("Add Item") 21 | } 22 | } 23 | }.environmentObject(marketViewModel) 24 | } 25 | } 26 | 27 | struct MarketHomeView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | MarketHomeView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Market/Home/Model/MarketItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MarketItem.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct MarketItem: Identifiable { 11 | let id: UUID = UUID() 12 | let name: String 13 | var price: Int 14 | 15 | mutating func updatePrice(value: Int?) { 16 | guard let _value = value else { return } 17 | price = _value 18 | } 19 | } 20 | 21 | extension MarketItem { 22 | static let items = [ 23 | MarketItem(name: "v1", price: 15), 24 | MarketItem(name: "v2", price: 30) 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Market/Home/ViewModel/MarketViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MarketViewModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | class MarketViewModel: ObservableObject { 11 | init() { 12 | items = MarketItem.items 13 | } 14 | 15 | @Published var items: [MarketItem] 16 | } 17 | 18 | //MARK: Market businsess 19 | extension MarketViewModel: MarketUses { 20 | func remove(id: UUID) -> Bool { 21 | guard let index = items.firstIndex(where: { item in item.id == id }) else { return false } 22 | items.remove(at: index) 23 | return true 24 | } 25 | 26 | func addItem(item: MarketItem) { 27 | items.append(item) 28 | } 29 | 30 | } 31 | 32 | protocol MarketUses { 33 | func addItem(item: MarketItem) 34 | func remove(id: UUID) -> Bool 35 | var items: [MarketItem] { get set } 36 | } 37 | 38 | 39 | extension MarketUses { 40 | mutating func remove(id: UUID) -> Bool { 41 | guard let index = items.firstIndex(where: { item in item.id == id }) else { return false } 42 | self.items.remove(at: index) 43 | return true 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Market/HomeDetail/MarketDetailView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MarketDetailView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MarketDetailView: View, BaseView { 11 | @StateObject private var marketDetailVM: MarketDetailViewModel = MarketDetailViewModel() 12 | @EnvironmentObject var marketVM: MarketViewModel 13 | @Environment(\.presentationMode) var presentationMode: Binding 14 | 15 | var body: some View { 16 | VStack { 17 | TextField("Name", text: $marketDetailVM.name) 18 | TextField("Count", text: $marketDetailVM.count) 19 | Button("Save") { 20 | saveItem() 21 | } 22 | } 23 | } 24 | } 25 | 26 | extension MarketDetailView { 27 | private func saveItem() { 28 | let result = marketDetailVM.save() 29 | guard result.0 == true else { return } 30 | marketVM.addItem(item: result.1!) 31 | dismiss() 32 | } 33 | 34 | } 35 | 36 | struct MarketDetailView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | MarketDetailView() 39 | } 40 | } 41 | 42 | protocol BaseView { 43 | var presentationMode: Binding { get } 44 | 45 | func dismiss(); 46 | } 47 | 48 | extension BaseView where Self: View { 49 | func dismiss() { 50 | presentationMode.wrappedValue.dismiss() 51 | } 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Market/HomeDetail/MarketDetailViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MarketDetailViewModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 14.06.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | class MarketDetailViewModel: ObservableObject { 11 | @Published var name: String = "" 12 | @Published var count: String = "" 13 | 14 | func save() -> (Bool,MarketItem?) { 15 | guard !name.isEmpty else { return (false,nil) } 16 | guard let value = Int(count) else { return (false,nil) } 17 | 18 | return (true,MarketItem(name: name, price: value)) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ModelList/ModelListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ModelListView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 25.10.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ModelListView: View { 11 | var body: some View { 12 | VStack { 13 | Text("Welcome List") 14 | .font(.largeTitle) 15 | .fontWeight(.light) 16 | 17 | List(TweetModel.tweets) { data in 18 | TweetCards(tweet: data) 19 | }.listStyle(.sidebar) 20 | } 21 | 22 | } 23 | } 24 | 25 | struct ModelListView_Previews: PreviewProvider { 26 | static var previews: some View { 27 | ModelListView() 28 | } 29 | } 30 | 31 | 32 | // User name 33 | // Body 34 | // Like 35 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ModelList/TweetCards.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TweetCards.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 25.10.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TweetCards: View { 11 | let tweet: TweetModel 12 | 13 | var body: some View { 14 | 15 | VStack(alignment: .leading) { 16 | Spacer() 17 | Text(tweet.userName).font(.title) 18 | Text("\(tweet.body)").font(.title3) 19 | 20 | if tweet.likeCount != nil { 21 | HStack { 22 | Text("\(tweet.likeCount!)").fontWeight(.light) 23 | Image(systemName: "heart.circle.fill").foregroundColor(.pink) 24 | Spacer() 25 | 26 | } 27 | } 28 | Spacer() 29 | 30 | 31 | 32 | }.padding(2).frame(height: 100, alignment: .top) 33 | .overlay(RoundedRectangle(cornerRadius: 10).stroke(.red, lineWidth: 2)).padding(2) 34 | } 35 | } 36 | 37 | struct TweetCards_Previews: PreviewProvider { 38 | static var previews: some View { 39 | TweetCards(tweet: TweetModel.fakeTweet).previewLayout(.sizeThatFits) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ModelList/TweetModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TweetModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 25.10.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | struct TweetModel: Identifiable { 11 | let id: UUID = UUID() 12 | let userName: String 13 | var body: String 14 | var likeCount: Int? 15 | } 16 | 17 | extension TweetModel { 18 | 19 | 20 | /// Sample tweet arrays 21 | static let tweets = [ 22 | TweetModel(userName: "vb", body: "hello1", likeCount: 10), 23 | TweetModel(userName: "vb2", body: "hello2", likeCount: 10), 24 | TweetModel(userName: "vb3", body: "hello3"), 25 | ] 26 | 27 | static let fakeTweet = TweetModel(userName: "vb", body: "hello1", likeCount: 10) 28 | } 29 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Navigation/NavigationUserModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationUserModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 8.11.2021. 6 | // 7 | 8 | import Foundation 9 | 10 | struct NavigationUserModel: Identifiable { 11 | let id: UUID = UUID() 12 | let name: String 13 | } 14 | 15 | 16 | extension NavigationUserModel { 17 | 18 | /// Samples navigation user model 19 | static let samples: [NavigationUserModel] = [ 20 | NavigationUserModel(name: "V"), 21 | NavigationUserModel(name: "V1"), 22 | NavigationUserModel(name: "V2"), 23 | NavigationUserModel(name: "V3") 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Navigation/NavigationUsers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NavigationUsers.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 8.11.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct NavigationUsers: View { 11 | 12 | @State private var isPresented: Bool = false 13 | 14 | var body: some View { 15 | NavigationView { 16 | List(NavigationUserModel.samples, id: \.id) { data in 17 | NavigationLink { 18 | UserViewDetail(user: data) 19 | } label: { 20 | Text(data.name) 21 | } 22 | 23 | }.sheet(isPresented: $isPresented, onDismiss: { 24 | print("") 25 | }, content: { 26 | Button("Hello") { 27 | isPresented.toggle() 28 | } 29 | }) 30 | .listStyle(GroupedListStyle()).navigationTitle(Text("Users")) 31 | .toolbar { 32 | ToolbarItem { 33 | Button("Open sheet") { 34 | isPresented.toggle() 35 | } 36 | } 37 | 38 | } 39 | } 40 | } 41 | } 42 | 43 | struct NavigationUsers_Previews: PreviewProvider { 44 | static var previews: some View { 45 | NavigationUsers() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/Navigation/UserViewDetail.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserViewDetail.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 8.11.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct UserViewDetail: View { 11 | let user: NavigationUserModel 12 | 13 | var body: some View { 14 | Text(user.name).font(.largeTitle) 15 | } 16 | } 17 | 18 | struct UserViewDetail_Previews: PreviewProvider { 19 | static var previews: some View { 20 | UserViewDetail(user: NavigationUserModel.samples.first!) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/PropertyWrapper/NumberCaseWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NumberCaseWrapper.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 28.06.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | @propertyWrapper struct NumberCaseWrapper { 11 | var wrappedValue: String { 12 | didSet { 13 | self.wrappedValue = calculateValue(value: wrappedValue) 14 | } 15 | } 16 | 17 | init(wrappedValue: String) { 18 | self.wrappedValue = Int(wrappedValue)?.description ?? "" 19 | } 20 | 21 | private func calculateValue(value: String) -> String { 22 | return Int(value)?.description ?? "" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/PropertyWrapper/PropetyWrapperView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PropetyWrapperView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 28.06.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct PropetyWrapperView: View { 11 | 12 | @State var userWrapperModel: UserWrapperModel = UserWrapperModel(name: "v", lastName: "b",age: "veli") 13 | 14 | var body: some View { 15 | VStack { 16 | Text(userWrapperModel.fullName) 17 | .font(.largeTitle) 18 | TextField("", text: $userWrapperModel.lastName) 19 | TextField("Number", text: $userWrapperModel.age) 20 | } 21 | 22 | } 23 | } 24 | 25 | struct PropetyWrapperView_Previews: PreviewProvider { 26 | static var previews: some View { 27 | PropetyWrapperView() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/PropertyWrapper/UpperCaseWrapper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UpperCaseWrapper.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 28.06.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | @propertyWrapper struct UpperCaseWrapper { 11 | var wrappedValue: String { 12 | didSet { 13 | wrappedValue = wrappedValue.uppercased() 14 | } 15 | } 16 | 17 | init(wrappedValue: String) { 18 | self.wrappedValue = wrappedValue.uppercased() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/PropertyWrapper/UserWrapperModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserWrapperModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 28.06.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | // Lastname is always bigger 11 | struct UserWrapperModel { 12 | var name: String 13 | @UpperCaseWrapper var lastName: String 14 | @NumberCaseWrapper var age: String 15 | 16 | var fullName: String { 17 | return "\(name) \(lastName) \(age) " 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ReqResViewModel/Model/User.swift: -------------------------------------------------------------------------------- 1 | // 2 | // User.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 31.05.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | // MARK: - Welcome 11 | struct User: Codable { 12 | let page, perPage, total, totalPages: Int 13 | let data: [Datum] 14 | let support: Support 15 | 16 | enum CodingKeys: String, CodingKey { 17 | case page 18 | case perPage = "per_page" 19 | case total 20 | case totalPages = "total_pages" 21 | case data, support 22 | } 23 | } 24 | 25 | // MARK: - Datum 26 | struct Datum: Codable, Identifiable { 27 | let id: Int 28 | let email, firstName, lastName: String 29 | let avatar: String 30 | 31 | enum CodingKeys: String, CodingKey { 32 | case id, email 33 | case firstName = "first_name" 34 | case lastName = "last_name" 35 | case avatar 36 | } 37 | } 38 | 39 | // MARK: - Support 40 | struct Support: Codable { 41 | let url: String 42 | let text: String 43 | } 44 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ReqResViewModel/Service/UserService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserService.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 31.05.2022. 6 | // 7 | 8 | import Foundation 9 | import Alamofire 10 | 11 | protocol IUserSerivce { 12 | 13 | func fetchUsers() async -> User? 14 | } 15 | 16 | 17 | struct UserService: IUserSerivce { 18 | 19 | func fetchUsers() async -> User? { 20 | let request = AF.request(ServicePath.users.toService()).serializingDecodable(User.self) 21 | let response = await request.response 22 | response.error?.showError() 23 | return response.value 24 | } 25 | 26 | } 27 | 28 | 29 | private enum ServicePath: String { 30 | case users = "users" 31 | 32 | func toService() -> String { 33 | return "https://reqres.in/api/\(rawValue)" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ReqResViewModel/View/UserView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 31.05.2022. 6 | // 7 | 8 | import SwiftUI 9 | import Kingfisher 10 | 11 | struct UserView: View { 12 | @StateObject var userViewModel = UserViewModel(userService: UserService()) 13 | 14 | var body: some View { 15 | if userViewModel.user == nil { 16 | LoadingView() 17 | } else { 18 | List(userViewModel.user?.data ?? []) { 19 | UserExtractedView(model: $0) 20 | } 21 | } 22 | } 23 | } 24 | 25 | 26 | 27 | struct UserView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | UserView() 30 | } 31 | } 32 | 33 | struct UserExtractedView: View { 34 | let model: Datum 35 | 36 | var body: some View { 37 | HStack { 38 | KFImage(URL(string: model.avatar )) 39 | .resizable() 40 | .frame(width:20, height: 20, 41 | alignment: .center) 42 | Text(model.firstName) 43 | Text(model.lastName) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/ReqResViewModel/ViewModel/UserViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserViewModel.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 31.05.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | class UserViewModel: ObservableObject { 12 | 13 | init(userService: IUserSerivce) { 14 | self.userService = userService 15 | Task.detached { 16 | await self.fetchWholeItems() 17 | } 18 | } 19 | 20 | let userService: IUserSerivce 21 | @Published var user: User? 22 | 23 | 24 | func fetchWholeItems() async { 25 | user = await userService.fetchUsers() 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /SwiftUITutorials/Features/SampleListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleListView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 11.10.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SampleListView: View { 11 | 12 | private let items: Array = [ 13 | "chevron.right", 14 | "chevron.left", 15 | "chevron.left", 16 | "chevron.left" 17 | ] 18 | 19 | var body: some View { 20 | List{ 21 | Section(header: Text("Sample").font(.largeTitle), content: { 22 | HStack{ 23 | Image(systemName: "person.crop.circle") 24 | Text("Profile") 25 | Spacer() 26 | Image(systemName: "chevron.right") 27 | } 28 | 29 | Text("Hello") 30 | Text("Hello") 31 | }) 32 | 33 | 34 | HStack{ 35 | Image(systemName: "person.crop.circle") 36 | Text("Profile") 37 | Spacer() 38 | Image(systemName: "chevron.right") 39 | } 40 | 41 | Text("Hello") 42 | HStack{ 43 | ForEach(items,id: \.self) { (item) in 44 | Image(systemName: item) 45 | } 46 | } 47 | 48 | 49 | } 50 | .listStyle(GroupedListStyle.init()) 51 | } 52 | } 53 | 54 | struct SampleListView_Previews: PreviewProvider { 55 | static var previews: some View { 56 | SampleListView() 57 | } 58 | } 59 | 60 | 61 | // 62 | -------------------------------------------------------------------------------- /SwiftUITutorials/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UIApplicationSupportsIndirectInputEvents 29 | 30 | UILaunchScreen 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /SwiftUITutorials/Localizable/LocaleKeys.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocaleKeys.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.08.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | enum LocaleKeys: String { 11 | case welcome = "welcome" 12 | } 13 | 14 | 15 | enum ProjectLanguages: String { 16 | case tr = "welcome" 17 | case en = "en" 18 | } 19 | -------------------------------------------------------------------------------- /SwiftUITutorials/Localizable/WelcomeView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WelcomeView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.08.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct WelcomeView: View { 11 | var body: some View { 12 | Text(LocaleKeys.welcome.rawValue) 13 | } 14 | } 15 | 16 | struct WelcomeView_Previews: PreviewProvider { 17 | static var previews: some View { 18 | WelcomeView().environment(\.locale, .init(identifier: ProjectLanguages.tr.rawValue)) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SwiftUITutorials/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUITutorials/SwiftUITutorialsApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUITutorialsApp.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 23.08.2021. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct SwiftUITutorialsApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | EnviromentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/19July/LabelView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LabelView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 19.07.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct LabelView: View { 11 | var body: some View { 12 | VStack { 13 | Label("Heart asdasd ", systemImage: Hearts.heartCircle.rawValue).labelStyle(DefaultLabelStyle()) 14 | Label("Heart2 asd asd", systemImage: Hearts.heartCircleFill.rawValue).labelStyle(IconOnlyLabelStyle()) 15 | Label("Heart3 xxxx", systemImage: Hearts.heartCircleFill.rawValue).labelStyle(TitleOnlyLabelStyle()) 16 | } 17 | } 18 | } 19 | 20 | enum Hearts: String { 21 | case heartCircle = "heart.circle" 22 | case heartCircleFill = "suit.heart.fill" 23 | case heartCircleSuit = "heart.circle.fill" 24 | } 25 | 26 | 27 | struct LabelView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | LabelView() 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/19July/TabGestureView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabGestureView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 19.07.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TabGestureView: View { 11 | @State private var isTap: Bool = false 12 | 13 | private var onTap: some Gesture { 14 | TapGesture(count: 3).onEnded { _ in 15 | self.isTap = !self.isTap 16 | } 17 | } 18 | 19 | var body: some View { 20 | RoundedRectangle(cornerSize: .init(width: 50, height: 20)).fill(isTap ? Color.red : Color.purple) .frame(width: 200, height: 200, alignment: .center).gesture(onTap) 21 | } 22 | } 23 | 24 | struct TabGestureView_Previews: PreviewProvider { 25 | static var previews: some View { 26 | TabGestureView() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/19July/TextEditingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextEditingView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 19.07.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TextEditingView: View { 11 | @State private var editorValue: String = "👻hello" 12 | 13 | var body: some View { 14 | VStack { 15 | TextEditor(text: $editorValue) 16 | .frame(width: 200, height: 200, alignment: .leading) 17 | .lineLimit(2).padding().background(Color.green) 18 | } 19 | } 20 | } 21 | 22 | struct TextEditingView_Previews: PreviewProvider { 23 | static var previews: some View { 24 | TextEditingView() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/19July/TimerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimerView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 19.07.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | //SubsciribvitonView 12 | struct TimerView: View { 13 | 14 | @State private var timeText: String = "vb" 15 | @State private var color: Color = Color.red 16 | @State private var colorValue: Int = 0 17 | 18 | private let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect() 19 | 20 | private var colorIsOdd: Bool { 21 | return ((colorValue % 2) != 0) 22 | } 23 | 24 | var body: some View { 25 | VStack { 26 | Text("\(colorValue % 2)") 27 | SubscriptionView(content: Text(timeText), publisher: timer) { time in 28 | timeText = String(describing: time) 29 | colorValue += 1 30 | print(colorValue / 2) 31 | 32 | } 33 | 34 | // Text(timer).onReceive(timer) { time in 35 | // 36 | // } 37 | }.background(colorIsOdd ? Color.red : Color.blue) 38 | } 39 | } 40 | 41 | struct TimerView_Previews: PreviewProvider { 42 | static var previews: some View { 43 | TimerView() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/Circle/CircleTextImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircleTextImageView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 4.10.2021. 6 | // 7 | 8 | import SwiftUI 9 | import Kingfisher 10 | 11 | struct CircleTextImageView: View { 12 | let title: String 13 | let imageUrl: String 14 | 15 | var body: some View { 16 | VStack { 17 | KFImage(URL(string: imageUrl)!).fade(duration: 0.25) .resizable().clipShape(/*@START_MENU_TOKEN@*/Circle()/*@END_MENU_TOKEN@*/).shadow(radius: /*@START_MENU_TOKEN@*/22/*@END_MENU_TOKEN@*/) 18 | Text(title).bold().italic() 19 | } 20 | } 21 | } 22 | 23 | struct CircleTextImageView_Previews: PreviewProvider { 24 | static var previews: some View { 25 | CircleTextImageView(title: "Hello", imageUrl: "https://picsum.photos/seed/picsum/200/300").frame(width: 200, height: 200, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).previewLayout(.sizeThatFits) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/TestView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.08.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TestView: View { 11 | var body: some View { 12 | Text("welcome") 13 | .bold() 14 | .modifier(CustomTile()) 15 | } 16 | } 17 | 18 | struct CustomTile: ViewModifier { 19 | func body(content: Content) -> some View { 20 | content 21 | .font(.largeTitle) 22 | .foregroundColor(.red) 23 | .shadow(radius: 2.0) 24 | } 25 | } 26 | 27 | struct TestView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | TestView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | SwiftUITutorials 4 | 5 | Created by Veli Bacik on 2.08.2022. 6 | 7 | */ 8 | "welcome" = "Welcome"; 9 | -------------------------------------------------------------------------------- /SwiftUITutorials/View/tr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | SwiftUITutorials 4 | 5 | Created by Veli Bacik on 2.08.2022. 6 | 7 | */ 8 | "welcome" = "Hosgeldiniz"; 9 | -------------------------------------------------------------------------------- /SwiftUITutorials/ViewModifier/HelloView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HelloView.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.08.2022. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct HelloView: View { 11 | var body: some View { 12 | VStack { 13 | Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) 14 | .bold() 15 | .modifier(AppTitle(isShadowHight: true)) 16 | 17 | Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) 18 | .bold() 19 | .titleStyle() 20 | } 21 | } 22 | } 23 | 24 | struct AppTitle: ViewModifier { 25 | let isShadowHight: Bool 26 | 27 | func body(content: Content) -> some View { 28 | content 29 | .font(.largeTitle) 30 | .foregroundColor(.blue) 31 | .shadow(radius: isShadowHight ? Shadows.hight.rawValue : Shadows.normal.rawValue) 32 | } 33 | } 34 | 35 | enum Shadows: Double { 36 | case normal = 2.0 37 | case hight = 10.0 38 | } 39 | 40 | struct HelloView_Previews: PreviewProvider { 41 | static var previews: some View { 42 | HelloView() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SwiftUITutorials/ViewModifier/View+Style.swift: -------------------------------------------------------------------------------- 1 | // 2 | // View+Style.swift 3 | // SwiftUITutorials 4 | // 5 | // Created by Veli Bacik on 2.08.2022. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | extension View { 12 | 13 | func titleStyle() -> some View { 14 | self.modifier(AppTitle(isShadowHight: false)) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | SwiftUITutorials 4 | 5 | Created by Veli Bacik on 2.08.2022. 6 | 7 | */ 8 | 9 | "welcome"="Welcome"; 10 | -------------------------------------------------------------------------------- /tr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | SwiftUITutorials 4 | 5 | Created by Veli Bacik on 2.08.2022. 6 | 7 | */ 8 | 9 | "welcome"="Hos Geldiniz"; 10 | --------------------------------------------------------------------------------