├── .DS_Store ├── .gitattributes ├── ToDo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── godwin.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ └── UserInterfaceState.xcuserstate │ │ └── godwina.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── godwin.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ └── xcschememanagement.plist │ └── godwina.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist └── ToDo ├── AppConstants └── AppConstants.swift ├── Assets.xcassets ├── AppIcon.appiconset │ ├── 1024.png │ ├── 120-1.png │ ├── 120.png │ ├── 180.png │ ├── 58.png │ ├── 60.png │ ├── 80.png │ ├── 87.png │ ├── Contents.json │ └── Icon-40.png ├── Complete.imageset │ ├── Contents.json │ ├── complete-1.png │ ├── complete-2.png │ └── complete.png ├── Completed.imageset │ ├── Contents.json │ ├── completed-1.png │ ├── completed-2.png │ └── completed.png ├── Contents.json ├── Importance.imageset │ ├── Contents.json │ ├── importance-1.png │ ├── importance-2.png │ └── importance.png ├── Importatant.imageset │ ├── Contents.json │ ├── importatnt-1.png │ ├── importatnt-2.png │ └── importatnt.png ├── SheduleOff.imageset │ ├── Contents.json │ ├── alarm-clock-2.png │ ├── alarm-clock-3.png │ └── alarm-clock-4.png ├── SheduleOn.imageset │ ├── Contents.json │ ├── alarm-clock-1.png │ ├── alarm-clock-2.png │ └── alarm-clock.png └── ToDo.imageset │ ├── Contents.json │ ├── to-do-list-1.png │ ├── to-do-list-2.png │ └── to-do-list.png ├── Custom └── TextField.swift ├── Delegate ├── AppDelegate.swift └── SceneDelegate.swift ├── Extension ├── AlertActionEx.swift ├── ButtonEx.swift ├── LabelEx.swift ├── TableEx.swift ├── ViewControllerEx.swift └── ViewEx.swift ├── Info.plist ├── Model └── ToDoModel.swift ├── StoryBoard └── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── ViewModel └── TodoListVM.swift └── Views ├── TableViewCell └── ToDoTableViewCell.swift └── ViewControllers ├── TaskDetailsVC.swift └── ToDoListVC.swift /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5AA7CFC825A04953004B2FD1 /* AppConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA7CFC725A04953004B2FD1 /* AppConstants.swift */; }; 11 | 5AA7CFCB25A05297004B2FD1 /* TodoListVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA7CFCA25A05297004B2FD1 /* TodoListVM.swift */; }; 12 | 5AA7CFDC25A09675004B2FD1 /* TableEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA7CFDB25A09675004B2FD1 /* TableEx.swift */; }; 13 | 5AA7CFDF25A09FA9004B2FD1 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA7CFDE25A09FA9004B2FD1 /* TextField.swift */; }; 14 | 5AA7CFE225A0B531004B2FD1 /* ViewControllerEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AA7CFE125A0B531004B2FD1 /* ViewControllerEx.swift */; }; 15 | 5AD8CA2D259DAE8A005B79CC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA2C259DAE8A005B79CC /* AppDelegate.swift */; }; 16 | 5AD8CA2F259DAE8A005B79CC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA2E259DAE8A005B79CC /* SceneDelegate.swift */; }; 17 | 5AD8CA31259DAE8A005B79CC /* ToDoListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA30259DAE8A005B79CC /* ToDoListVC.swift */; }; 18 | 5AD8CA34259DAE8A005B79CC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5AD8CA32259DAE8A005B79CC /* Main.storyboard */; }; 19 | 5AD8CA36259DAE91005B79CC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5AD8CA35259DAE91005B79CC /* Assets.xcassets */; }; 20 | 5AD8CA39259DAE91005B79CC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5AD8CA37259DAE91005B79CC /* LaunchScreen.storyboard */; }; 21 | 5AD8CA46259DB118005B79CC /* ToDoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA45259DB118005B79CC /* ToDoTableViewCell.swift */; }; 22 | 5AD8CA4A259DB356005B79CC /* ToDoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA49259DB356005B79CC /* ToDoModel.swift */; }; 23 | 5AD8CA5C259DD3BF005B79CC /* LabelEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA5B259DD3BF005B79CC /* LabelEx.swift */; }; 24 | 5AD8CA5F259DE066005B79CC /* ViewEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA5E259DE066005B79CC /* ViewEx.swift */; }; 25 | 5AD8CA65259DFD29005B79CC /* ButtonEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA64259DFD29005B79CC /* ButtonEx.swift */; }; 26 | 5AD8CA68259E246E005B79CC /* TaskDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA67259E246E005B79CC /* TaskDetailsVC.swift */; }; 27 | 5AD8CA6B259E404F005B79CC /* AlertActionEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AD8CA6A259E404F005B79CC /* AlertActionEx.swift */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 5AA7CFC725A04953004B2FD1 /* AppConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConstants.swift; sourceTree = ""; }; 32 | 5AA7CFCA25A05297004B2FD1 /* TodoListVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoListVM.swift; sourceTree = ""; }; 33 | 5AA7CFDB25A09675004B2FD1 /* TableEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableEx.swift; sourceTree = ""; }; 34 | 5AA7CFDE25A09FA9004B2FD1 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = ""; }; 35 | 5AA7CFE125A0B531004B2FD1 /* ViewControllerEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerEx.swift; sourceTree = ""; }; 36 | 5AD8CA29259DAE8A005B79CC /* ToDo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ToDo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 5AD8CA2C259DAE8A005B79CC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 38 | 5AD8CA2E259DAE8A005B79CC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 39 | 5AD8CA30259DAE8A005B79CC /* ToDoListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoListVC.swift; sourceTree = ""; }; 40 | 5AD8CA33259DAE8A005B79CC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 41 | 5AD8CA35259DAE91005B79CC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 42 | 5AD8CA38259DAE91005B79CC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 43 | 5AD8CA3A259DAE91005B79CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 44 | 5AD8CA45259DB118005B79CC /* ToDoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoTableViewCell.swift; sourceTree = ""; }; 45 | 5AD8CA49259DB356005B79CC /* ToDoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoModel.swift; sourceTree = ""; }; 46 | 5AD8CA5B259DD3BF005B79CC /* LabelEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelEx.swift; sourceTree = ""; }; 47 | 5AD8CA5E259DE066005B79CC /* ViewEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewEx.swift; sourceTree = ""; }; 48 | 5AD8CA64259DFD29005B79CC /* ButtonEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonEx.swift; sourceTree = ""; }; 49 | 5AD8CA67259E246E005B79CC /* TaskDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskDetailsVC.swift; sourceTree = ""; }; 50 | 5AD8CA6A259E404F005B79CC /* AlertActionEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertActionEx.swift; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | 5AD8CA26259DAE8A005B79CC /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 5A7B3D9A275A5AFD009C7257 /* Custom */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 5AA7CFDE25A09FA9004B2FD1 /* TextField.swift */, 68 | ); 69 | path = Custom; 70 | sourceTree = ""; 71 | }; 72 | 5AA7CFD325A0937B004B2FD1 /* Model */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 5AD8CA49259DB356005B79CC /* ToDoModel.swift */, 76 | ); 77 | path = Model; 78 | sourceTree = ""; 79 | }; 80 | 5AA7CFD425A0938D004B2FD1 /* ViewModel */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 5AA7CFCA25A05297004B2FD1 /* TodoListVM.swift */, 84 | ); 85 | path = ViewModel; 86 | sourceTree = ""; 87 | }; 88 | 5AA7CFD525A093AD004B2FD1 /* TableViewCell */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 5AD8CA45259DB118005B79CC /* ToDoTableViewCell.swift */, 92 | ); 93 | path = TableViewCell; 94 | sourceTree = ""; 95 | }; 96 | 5AA7CFD625A093BD004B2FD1 /* AppConstants */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 5AA7CFC725A04953004B2FD1 /* AppConstants.swift */, 100 | ); 101 | path = AppConstants; 102 | sourceTree = ""; 103 | }; 104 | 5AA7CFD725A093D9004B2FD1 /* StoryBoard */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 5AD8CA32259DAE8A005B79CC /* Main.storyboard */, 108 | 5AD8CA37259DAE91005B79CC /* LaunchScreen.storyboard */, 109 | ); 110 | path = StoryBoard; 111 | sourceTree = ""; 112 | }; 113 | 5AA7CFD825A093FC004B2FD1 /* Views */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 5AD8CA6D259E42DA005B79CC /* ViewControllers */, 117 | 5AA7CFD525A093AD004B2FD1 /* TableViewCell */, 118 | ); 119 | path = Views; 120 | sourceTree = ""; 121 | }; 122 | 5AD8CA20259DAE8A005B79CC = { 123 | isa = PBXGroup; 124 | children = ( 125 | 5AD8CA2B259DAE8A005B79CC /* ToDo */, 126 | 5AD8CA2A259DAE8A005B79CC /* Products */, 127 | ); 128 | sourceTree = ""; 129 | }; 130 | 5AD8CA2A259DAE8A005B79CC /* Products */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 5AD8CA29259DAE8A005B79CC /* ToDo.app */, 134 | ); 135 | name = Products; 136 | sourceTree = ""; 137 | }; 138 | 5AD8CA2B259DAE8A005B79CC /* ToDo */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 5AA7CFD325A0937B004B2FD1 /* Model */, 142 | 5AA7CFD825A093FC004B2FD1 /* Views */, 143 | 5AA7CFD425A0938D004B2FD1 /* ViewModel */, 144 | 5A7B3D9A275A5AFD009C7257 /* Custom */, 145 | 5AD8CA48259DB214005B79CC /* Delegate */, 146 | 5AD8CA4F259DCFC6005B79CC /* Extension */, 147 | 5AA7CFD625A093BD004B2FD1 /* AppConstants */, 148 | 5AA7CFD725A093D9004B2FD1 /* StoryBoard */, 149 | 5AD8CA35259DAE91005B79CC /* Assets.xcassets */, 150 | 5AD8CA3A259DAE91005B79CC /* Info.plist */, 151 | ); 152 | path = ToDo; 153 | sourceTree = ""; 154 | }; 155 | 5AD8CA48259DB214005B79CC /* Delegate */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 5AD8CA2C259DAE8A005B79CC /* AppDelegate.swift */, 159 | 5AD8CA2E259DAE8A005B79CC /* SceneDelegate.swift */, 160 | ); 161 | path = Delegate; 162 | sourceTree = ""; 163 | }; 164 | 5AD8CA4F259DCFC6005B79CC /* Extension */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 5AD8CA5E259DE066005B79CC /* ViewEx.swift */, 168 | 5AD8CA5B259DD3BF005B79CC /* LabelEx.swift */, 169 | 5AA7CFDB25A09675004B2FD1 /* TableEx.swift */, 170 | 5AD8CA64259DFD29005B79CC /* ButtonEx.swift */, 171 | 5AD8CA6A259E404F005B79CC /* AlertActionEx.swift */, 172 | 5AA7CFE125A0B531004B2FD1 /* ViewControllerEx.swift */, 173 | ); 174 | path = Extension; 175 | sourceTree = ""; 176 | }; 177 | 5AD8CA6D259E42DA005B79CC /* ViewControllers */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 5AD8CA30259DAE8A005B79CC /* ToDoListVC.swift */, 181 | 5AD8CA67259E246E005B79CC /* TaskDetailsVC.swift */, 182 | ); 183 | path = ViewControllers; 184 | sourceTree = ""; 185 | }; 186 | /* End PBXGroup section */ 187 | 188 | /* Begin PBXNativeTarget section */ 189 | 5AD8CA28259DAE8A005B79CC /* ToDo */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = 5AD8CA3D259DAE91005B79CC /* Build configuration list for PBXNativeTarget "ToDo" */; 192 | buildPhases = ( 193 | 5AD8CA25259DAE8A005B79CC /* Sources */, 194 | 5AD8CA26259DAE8A005B79CC /* Frameworks */, 195 | 5AD8CA27259DAE8A005B79CC /* Resources */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | ); 201 | name = ToDo; 202 | productName = ToDo; 203 | productReference = 5AD8CA29259DAE8A005B79CC /* ToDo.app */; 204 | productType = "com.apple.product-type.application"; 205 | }; 206 | /* End PBXNativeTarget section */ 207 | 208 | /* Begin PBXProject section */ 209 | 5AD8CA21259DAE8A005B79CC /* Project object */ = { 210 | isa = PBXProject; 211 | attributes = { 212 | LastSwiftUpdateCheck = 1220; 213 | LastUpgradeCheck = 1310; 214 | TargetAttributes = { 215 | 5AD8CA28259DAE8A005B79CC = { 216 | CreatedOnToolsVersion = 12.2; 217 | }; 218 | }; 219 | }; 220 | buildConfigurationList = 5AD8CA24259DAE8A005B79CC /* Build configuration list for PBXProject "ToDo" */; 221 | compatibilityVersion = "Xcode 9.3"; 222 | developmentRegion = en; 223 | hasScannedForEncodings = 0; 224 | knownRegions = ( 225 | en, 226 | Base, 227 | ); 228 | mainGroup = 5AD8CA20259DAE8A005B79CC; 229 | productRefGroup = 5AD8CA2A259DAE8A005B79CC /* Products */; 230 | projectDirPath = ""; 231 | projectRoot = ""; 232 | targets = ( 233 | 5AD8CA28259DAE8A005B79CC /* ToDo */, 234 | ); 235 | }; 236 | /* End PBXProject section */ 237 | 238 | /* Begin PBXResourcesBuildPhase section */ 239 | 5AD8CA27259DAE8A005B79CC /* Resources */ = { 240 | isa = PBXResourcesBuildPhase; 241 | buildActionMask = 2147483647; 242 | files = ( 243 | 5AD8CA39259DAE91005B79CC /* LaunchScreen.storyboard in Resources */, 244 | 5AD8CA36259DAE91005B79CC /* Assets.xcassets in Resources */, 245 | 5AD8CA34259DAE8A005B79CC /* Main.storyboard in Resources */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | /* End PBXResourcesBuildPhase section */ 250 | 251 | /* Begin PBXSourcesBuildPhase section */ 252 | 5AD8CA25259DAE8A005B79CC /* Sources */ = { 253 | isa = PBXSourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | 5AD8CA31259DAE8A005B79CC /* ToDoListVC.swift in Sources */, 257 | 5AD8CA2D259DAE8A005B79CC /* AppDelegate.swift in Sources */, 258 | 5AA7CFE225A0B531004B2FD1 /* ViewControllerEx.swift in Sources */, 259 | 5AD8CA65259DFD29005B79CC /* ButtonEx.swift in Sources */, 260 | 5AA7CFDF25A09FA9004B2FD1 /* TextField.swift in Sources */, 261 | 5AA7CFC825A04953004B2FD1 /* AppConstants.swift in Sources */, 262 | 5AA7CFCB25A05297004B2FD1 /* TodoListVM.swift in Sources */, 263 | 5AD8CA4A259DB356005B79CC /* ToDoModel.swift in Sources */, 264 | 5AD8CA2F259DAE8A005B79CC /* SceneDelegate.swift in Sources */, 265 | 5AD8CA46259DB118005B79CC /* ToDoTableViewCell.swift in Sources */, 266 | 5AA7CFDC25A09675004B2FD1 /* TableEx.swift in Sources */, 267 | 5AD8CA68259E246E005B79CC /* TaskDetailsVC.swift in Sources */, 268 | 5AD8CA6B259E404F005B79CC /* AlertActionEx.swift in Sources */, 269 | 5AD8CA5F259DE066005B79CC /* ViewEx.swift in Sources */, 270 | 5AD8CA5C259DD3BF005B79CC /* LabelEx.swift in Sources */, 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | /* End PBXSourcesBuildPhase section */ 275 | 276 | /* Begin PBXVariantGroup section */ 277 | 5AD8CA32259DAE8A005B79CC /* Main.storyboard */ = { 278 | isa = PBXVariantGroup; 279 | children = ( 280 | 5AD8CA33259DAE8A005B79CC /* Base */, 281 | ); 282 | name = Main.storyboard; 283 | sourceTree = ""; 284 | }; 285 | 5AD8CA37259DAE91005B79CC /* LaunchScreen.storyboard */ = { 286 | isa = PBXVariantGroup; 287 | children = ( 288 | 5AD8CA38259DAE91005B79CC /* Base */, 289 | ); 290 | name = LaunchScreen.storyboard; 291 | sourceTree = ""; 292 | }; 293 | /* End PBXVariantGroup section */ 294 | 295 | /* Begin XCBuildConfiguration section */ 296 | 5AD8CA3B259DAE91005B79CC /* Debug */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | ALWAYS_SEARCH_USER_PATHS = NO; 300 | CLANG_ANALYZER_NONNULL = YES; 301 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 302 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 303 | CLANG_CXX_LIBRARY = "libc++"; 304 | CLANG_ENABLE_MODULES = YES; 305 | CLANG_ENABLE_OBJC_ARC = YES; 306 | CLANG_ENABLE_OBJC_WEAK = YES; 307 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 308 | CLANG_WARN_BOOL_CONVERSION = YES; 309 | CLANG_WARN_COMMA = YES; 310 | CLANG_WARN_CONSTANT_CONVERSION = YES; 311 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 312 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 313 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 314 | CLANG_WARN_EMPTY_BODY = YES; 315 | CLANG_WARN_ENUM_CONVERSION = YES; 316 | CLANG_WARN_INFINITE_RECURSION = YES; 317 | CLANG_WARN_INT_CONVERSION = YES; 318 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 319 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 320 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 321 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 322 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 323 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 324 | CLANG_WARN_STRICT_PROTOTYPES = YES; 325 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 326 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 327 | CLANG_WARN_UNREACHABLE_CODE = YES; 328 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 329 | COPY_PHASE_STRIP = NO; 330 | DEBUG_INFORMATION_FORMAT = dwarf; 331 | ENABLE_STRICT_OBJC_MSGSEND = YES; 332 | ENABLE_TESTABILITY = YES; 333 | GCC_C_LANGUAGE_STANDARD = gnu11; 334 | GCC_DYNAMIC_NO_PIC = NO; 335 | GCC_NO_COMMON_BLOCKS = YES; 336 | GCC_OPTIMIZATION_LEVEL = 0; 337 | GCC_PREPROCESSOR_DEFINITIONS = ( 338 | "DEBUG=1", 339 | "$(inherited)", 340 | ); 341 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 342 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 343 | GCC_WARN_UNDECLARED_SELECTOR = YES; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | IPHONEOS_DEPLOYMENT_TARGET = 14.2; 348 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 349 | MTL_FAST_MATH = YES; 350 | ONLY_ACTIVE_ARCH = YES; 351 | SDKROOT = iphoneos; 352 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 353 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 354 | }; 355 | name = Debug; 356 | }; 357 | 5AD8CA3C259DAE91005B79CC /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_MODULES = YES; 366 | CLANG_ENABLE_OBJC_ARC = YES; 367 | CLANG_ENABLE_OBJC_WEAK = YES; 368 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 369 | CLANG_WARN_BOOL_CONVERSION = YES; 370 | CLANG_WARN_COMMA = YES; 371 | CLANG_WARN_CONSTANT_CONVERSION = YES; 372 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 373 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 374 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 375 | CLANG_WARN_EMPTY_BODY = YES; 376 | CLANG_WARN_ENUM_CONVERSION = YES; 377 | CLANG_WARN_INFINITE_RECURSION = YES; 378 | CLANG_WARN_INT_CONVERSION = YES; 379 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 380 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 381 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 382 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 383 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 384 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 385 | CLANG_WARN_STRICT_PROTOTYPES = YES; 386 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 387 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 388 | CLANG_WARN_UNREACHABLE_CODE = YES; 389 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 390 | COPY_PHASE_STRIP = NO; 391 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 392 | ENABLE_NS_ASSERTIONS = NO; 393 | ENABLE_STRICT_OBJC_MSGSEND = YES; 394 | GCC_C_LANGUAGE_STANDARD = gnu11; 395 | GCC_NO_COMMON_BLOCKS = YES; 396 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 397 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 398 | GCC_WARN_UNDECLARED_SELECTOR = YES; 399 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 400 | GCC_WARN_UNUSED_FUNCTION = YES; 401 | GCC_WARN_UNUSED_VARIABLE = YES; 402 | IPHONEOS_DEPLOYMENT_TARGET = 14.2; 403 | MTL_ENABLE_DEBUG_INFO = NO; 404 | MTL_FAST_MATH = YES; 405 | SDKROOT = iphoneos; 406 | SWIFT_COMPILATION_MODE = wholemodule; 407 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 408 | VALIDATE_PRODUCT = YES; 409 | }; 410 | name = Release; 411 | }; 412 | 5AD8CA3E259DAE91005B79CC /* Debug */ = { 413 | isa = XCBuildConfiguration; 414 | buildSettings = { 415 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 416 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 417 | CODE_SIGN_STYLE = Manual; 418 | DEVELOPMENT_TEAM = ""; 419 | INFOPLIST_FILE = ToDo/Info.plist; 420 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 421 | LD_RUNPATH_SEARCH_PATHS = ( 422 | "$(inherited)", 423 | "@executable_path/Frameworks", 424 | ); 425 | PRODUCT_BUNDLE_IDENTIFIER = Godwin.ToDo; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | PROVISIONING_PROFILE_SPECIFIER = ""; 428 | SWIFT_VERSION = 5.0; 429 | TARGETED_DEVICE_FAMILY = 1; 430 | }; 431 | name = Debug; 432 | }; 433 | 5AD8CA3F259DAE91005B79CC /* Release */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 437 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 438 | CODE_SIGN_STYLE = Manual; 439 | DEVELOPMENT_TEAM = ""; 440 | INFOPLIST_FILE = ToDo/Info.plist; 441 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 442 | LD_RUNPATH_SEARCH_PATHS = ( 443 | "$(inherited)", 444 | "@executable_path/Frameworks", 445 | ); 446 | PRODUCT_BUNDLE_IDENTIFIER = Godwin.ToDo; 447 | PRODUCT_NAME = "$(TARGET_NAME)"; 448 | PROVISIONING_PROFILE_SPECIFIER = ""; 449 | SWIFT_VERSION = 5.0; 450 | TARGETED_DEVICE_FAMILY = 1; 451 | }; 452 | name = Release; 453 | }; 454 | /* End XCBuildConfiguration section */ 455 | 456 | /* Begin XCConfigurationList section */ 457 | 5AD8CA24259DAE8A005B79CC /* Build configuration list for PBXProject "ToDo" */ = { 458 | isa = XCConfigurationList; 459 | buildConfigurations = ( 460 | 5AD8CA3B259DAE91005B79CC /* Debug */, 461 | 5AD8CA3C259DAE91005B79CC /* Release */, 462 | ); 463 | defaultConfigurationIsVisible = 0; 464 | defaultConfigurationName = Release; 465 | }; 466 | 5AD8CA3D259DAE91005B79CC /* Build configuration list for PBXNativeTarget "ToDo" */ = { 467 | isa = XCConfigurationList; 468 | buildConfigurations = ( 469 | 5AD8CA3E259DAE91005B79CC /* Debug */, 470 | 5AD8CA3F259DAE91005B79CC /* Release */, 471 | ); 472 | defaultConfigurationIsVisible = 0; 473 | defaultConfigurationName = Release; 474 | }; 475 | /* End XCConfigurationList section */ 476 | }; 477 | rootObject = 5AD8CA21259DAE8A005B79CC /* Project object */; 478 | } 479 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/project.xcworkspace/xcuserdata/godwin.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/project.xcworkspace/xcuserdata/godwin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo.xcodeproj/project.xcworkspace/xcuserdata/godwin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ToDo.xcodeproj/project.xcworkspace/xcuserdata/godwina.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo.xcodeproj/project.xcworkspace/xcuserdata/godwina.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ToDo.xcodeproj/xcuserdata/godwin.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 | 72 | 73 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/xcuserdata/godwin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ToDo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ToDo.xcodeproj/xcuserdata/godwina.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ToDo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ToDo/AppConstants/AppConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppConstants.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | enum FontSize: CGFloat { 11 | 12 | case title = 16 13 | case subtite = 10 14 | } 15 | 16 | 17 | enum Categories: String { 18 | 19 | case DateCreated = "Created" 20 | case DateEdited = "Last Edited" 21 | case Priority = "Important" 22 | case Completed = "Completed" 23 | case Shedule = "Shedule" 24 | case Default = "Cancel" 25 | } 26 | 27 | enum AppTitle: String { 28 | 29 | case listVCTitle = "To Do List" 30 | case addNew = "Add New" 31 | case deleteTask = "Delete task" 32 | } 33 | 34 | enum AppButton { 35 | 36 | case Complete 37 | case Important 38 | case Shedule 39 | 40 | 41 | func imageName(enable: Bool = false) -> String { 42 | switch self { 43 | case .Complete: 44 | return enable ? "Complete" : "Completed" 45 | case .Important: 46 | return enable ? "Importatant" : "Importance" 47 | case .Shedule: 48 | return enable ? "SheduleOff" : "SheduleOn" 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/120-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon-40.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "60.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "58.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "87.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "80.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "120-1.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "120.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "180.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "1024.png", 53 | "idiom" : "ios-marketing", 54 | "scale" : "1x", 55 | "size" : "1024x1024" 56 | } 57 | ], 58 | "info" : { 59 | "author" : "xcode", 60 | "version" : 1 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Complete.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "complete.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "complete-1.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "complete-2.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Complete.imageset/complete-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Complete.imageset/complete-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Complete.imageset/complete-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Complete.imageset/complete-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Complete.imageset/complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Complete.imageset/complete.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Completed.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "completed.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "completed-1.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "completed-2.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Completed.imageset/completed-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Completed.imageset/completed-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Completed.imageset/completed-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Completed.imageset/completed-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Completed.imageset/completed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Completed.imageset/completed.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importance.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "importance.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "importance-1.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "importance-2.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importance.imageset/importance-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Importance.imageset/importance-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importance.imageset/importance-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Importance.imageset/importance-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importance.imageset/importance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Importance.imageset/importance.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importatant.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "importatnt.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "importatnt-1.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "importatnt-2.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importatant.imageset/importatnt-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Importatant.imageset/importatnt-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importatant.imageset/importatnt-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Importatant.imageset/importatnt-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/Importatant.imageset/importatnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/Importatant.imageset/importatnt.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOff.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "alarm-clock-4.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "alarm-clock-2.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "alarm-clock-3.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOff.imageset/alarm-clock-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/SheduleOff.imageset/alarm-clock-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOff.imageset/alarm-clock-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/SheduleOff.imageset/alarm-clock-3.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOff.imageset/alarm-clock-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/SheduleOff.imageset/alarm-clock-4.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "alarm-clock-1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "alarm-clock.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "alarm-clock-2.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOn.imageset/alarm-clock-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/SheduleOn.imageset/alarm-clock-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOn.imageset/alarm-clock-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/SheduleOn.imageset/alarm-clock-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/SheduleOn.imageset/alarm-clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/SheduleOn.imageset/alarm-clock.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/ToDo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "to-do-list.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "to-do-list-1.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "to-do-list-2.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/ToDo.imageset/to-do-list-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/ToDo.imageset/to-do-list-1.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/ToDo.imageset/to-do-list-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/ToDo.imageset/to-do-list-2.png -------------------------------------------------------------------------------- /ToDo/Assets.xcassets/ToDo.imageset/to-do-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GodwiniOS/Todo/4ca9005f3e445c2e84d2a2485471416648553236/ToDo/Assets.xcassets/ToDo.imageset/to-do-list.png -------------------------------------------------------------------------------- /ToDo/Custom/TextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextField.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | class TextField: UITextField { 11 | 12 | let padding = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) 13 | 14 | override func textRect(forBounds bounds: CGRect) -> CGRect { 15 | return bounds.inset(by: padding) 16 | } 17 | 18 | override func placeholderRect(forBounds bounds: CGRect) -> CGRect { 19 | return bounds.inset(by: padding) 20 | } 21 | 22 | override func editingRect(forBounds bounds: CGRect) -> CGRect { 23 | return bounds.inset(by: padding) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ToDo/Delegate/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | @main class AppDelegate: UIResponder, UIApplicationDelegate {} 11 | -------------------------------------------------------------------------------- /ToDo/Delegate/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | var window: UIWindow? 12 | } 13 | -------------------------------------------------------------------------------- /ToDo/Extension/AlertActionEx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AlertActionEx.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIAlertAction { 11 | 12 | func prepare(color: UIColor = .black){ 13 | setValue(color, forKey: "titleTextColor") 14 | } 15 | } 16 | 17 | 18 | extension Date { 19 | 20 | func time() -> String { 21 | 22 | var hour = Calendar.current.component(.hour, from: self) 23 | let minutes = Calendar.current.component(.minute, from: self) 24 | let day = Calendar.current.component(.day, from: self) 25 | let month = Calendar.current.component(.month, from: self) 26 | let year = Calendar.current.component(.year, from: self) 27 | 28 | var Median = "AM" 29 | if hour > 12 { 30 | hour -= 12 31 | Median = "PM" 32 | } 33 | return "\(hour):\(minutes) \(Median) \(day)-\(month)-\(year)" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ToDo/Extension/ButtonEx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ButtonEx.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIButton { 11 | 12 | func setImage(name: AppButton){ 13 | setImage(UIImage(named: name.imageName()),for: .normal) 14 | } 15 | 16 | func changeState(button: AppButton,isEnable: Bool){ 17 | setImage(UIImage(named: button.imageName(enable: isEnable)), 18 | for: .normal) 19 | 20 | } 21 | 22 | func setTitle(_ title: AppTitle) { 23 | setTitle(title.rawValue, for: .normal) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ToDo/Extension/LabelEx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LabelEx.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | import UIKit 8 | 9 | 10 | extension UILabel{ 11 | 12 | func prepareTextField(size: FontSize) { 13 | font = font.withSize(size.rawValue) 14 | textColor = .black 15 | } 16 | 17 | func strikeThrough() { 18 | let attrString = NSAttributedString(string: text ?? "", attributes: [NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue]) 19 | attributedText = attrString 20 | textColor = .gray 21 | } 22 | } 23 | 24 | 25 | extension UITextField{ 26 | 27 | func strikeThrough(enable: Bool) { 28 | 29 | if enable { 30 | let attrString = NSAttributedString(string: text ?? "", attributes: [NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue]) 31 | attributedText = attrString 32 | textColor = .gray 33 | } else { 34 | attributedText = NSAttributedString(string: text ?? "") 35 | textColor = .black 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ToDo/Extension/TableEx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableEx.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UITableView { 11 | 12 | func registerCell() { 13 | self.register(ToDoTableViewCell.self, forCellReuseIdentifier: "DefaultCell") 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ToDo/Extension/ViewControllerEx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewControllerEx.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | extension UIViewController { 12 | 13 | func prepareBarButton() { 14 | title = "List" 15 | 16 | self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.clear] 17 | 18 | let barButton = UIBarButtonItem(title: AppTitle.listVCTitle.rawValue, 19 | style: .plain, 20 | target: self, 21 | action: nil) 22 | navigationItem.leftBarButtonItem = barButton 23 | navigationItem.leftBarButtonItem?.tintColor = .black 24 | navigationItem.rightBarButtonItem?.tintColor = .black 25 | barButton.setTitleTextAttributes([NSAttributedString.Key.font: UIFont(name: "Helvetica-Bold", size: 20)!], 26 | for: .normal) 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ToDo/Extension/ViewEx.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewEx.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIView { 11 | 12 | func prepareLayout(_ attribute: NSLayoutConstraint.Attribute, 13 | toItem :UIView? = nil, 14 | constant: CGFloat = 0) { 15 | 16 | translatesAutoresizingMaskIntoConstraints = false 17 | let withItem: UIView! = toItem != nil ? toItem! : superview 18 | let withAttribute: NSLayoutConstraint.Attribute! = toItem != nil ? .bottom : attribute 19 | 20 | let layout = NSLayoutConstraint(item: self, 21 | attribute: attribute, 22 | relatedBy: .equal, 23 | toItem: withItem, 24 | attribute: withAttribute, 25 | multiplier: 1, 26 | constant: constant) 27 | NSLayoutConstraint.activate([layout]) 28 | } 29 | 30 | 31 | func prepareHeight(constant: CGFloat) { 32 | 33 | let constraint = NSLayoutConstraint( 34 | item: self, 35 | attribute: .height, 36 | relatedBy: .equal, 37 | toItem: nil, 38 | attribute: .notAnAttribute, 39 | multiplier: 1.0, 40 | constant: constant) 41 | NSLayoutConstraint.activate([constraint]) 42 | } 43 | 44 | func prepareWidth(constant: CGFloat) { 45 | 46 | let constraint = NSLayoutConstraint( 47 | item: self, 48 | attribute: .width, 49 | relatedBy: .equal, 50 | toItem: nil, 51 | attribute: .notAnAttribute, 52 | multiplier: 1.0, 53 | constant: constant) 54 | NSLayoutConstraint.activate([constraint]) 55 | } 56 | 57 | 58 | func cornerRadius(constant: CGFloat = 10,color: UIColor, 59 | width: CGFloat = 1){ 60 | layer.cornerRadius = constant; 61 | layer.masksToBounds = true; 62 | layer.borderWidth = width 63 | layer.borderColor = color.cgColor 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ToDo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /ToDo/Model/ToDoModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoModel.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import Foundation 9 | 10 | struct ToDoModel { 11 | 12 | var title: String 13 | var index: Int? 14 | 15 | var isDone: Bool = false 16 | var isSheduled: Bool = false 17 | var isImportant: Bool = false 18 | 19 | var createdTime: Date = Date() 20 | var sheduleTime: Date = Date() 21 | var lastEditedTime: Date = Date() 22 | 23 | mutating func saveChanges(of item: ToDoModel){ 24 | 25 | isSheduled = item.isSheduled 26 | isDone = item.isDone 27 | isImportant = item.isImportant 28 | title = item.title 29 | sheduleTime = item.sheduleTime 30 | lastEditedTime = Date() 31 | index = nil 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ToDo/StoryBoard/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ToDo/StoryBoard/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /ToDo/ViewModel/TodoListVM.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodoListVM.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | protocol TodosListDelegate: AnyObject { 12 | func reloadData() 13 | } 14 | 15 | class TodosListVM { 16 | 17 | // MARK: - Properties 18 | weak var delegate : TodosListDelegate? 19 | var items = [ToDoModel]() 20 | var count: Int { return items.count } 21 | var canSort: Bool { return items.count < 2 } 22 | var sortType: Categories = .Default 23 | let sortCategories: [Categories] = [.Priority,.Completed,.Shedule,.Default,.DateCreated,.DateEdited] 24 | 25 | // MARK: - Methods 26 | func addNew(text: String) { 27 | let todoItem = ToDoModel(title: text) 28 | items.insert(todoItem, at: 0) 29 | sortType = .Default 30 | } 31 | 32 | 33 | // MARK: - When User Prioritize Task 34 | func makeImportant(index: Int) { 35 | 36 | sortType = .Default 37 | var item = items[index] 38 | if item.isImportant { 39 | items[index].isImportant = false 40 | items[index].lastEditedTime = Date() 41 | } else { 42 | item.isImportant = true 43 | item.lastEditedTime = Date() 44 | items.remove(at: index) 45 | items.insert(item, at: findImportantIndex() ?? 0) 46 | } 47 | } 48 | 49 | // MARK: - When User Complete Task 50 | func makeComplete(index: Int) { 51 | 52 | sortType = .Default 53 | var item = items[index] 54 | if item.isDone { 55 | items[index].isDone = false 56 | items[index].lastEditedTime = Date() 57 | 58 | } else { 59 | item.isDone = true 60 | item.lastEditedTime = Date() 61 | items.remove(at: index) 62 | items.insert(item, at: findCompletedIndex() ?? count) 63 | } 64 | } 65 | 66 | // MARK: - To Bring Task Top Of List 67 | private func findImportantIndex() -> Int? { 68 | for index in 0.. Int? { 76 | for index in 0.. $1.lastEditedTime } 91 | case .Completed: 92 | list.sort { $0.isDone && !$1.isDone } 93 | case .Priority: 94 | list.sort { $0.isImportant && !$1.isImportant } 95 | case .Shedule: 96 | list.sort { $0.sheduleTime > $1.sheduleTime } 97 | default: print("") 98 | } 99 | 100 | items = list 101 | sortType = type 102 | delegate?.reloadData() 103 | } 104 | 105 | // MARK: - To Share selected Item Data to Details Screen 106 | func prepareDetails(index: Int) -> ToDoModel{ 107 | items[index].index = index 108 | sortType = .Default 109 | return items[index] 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /ToDo/Views/TableViewCell/ToDoTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoTableViewCell.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | protocol ToDoTVCDelegate: AnyObject { 12 | func completeButtonClicked(index: Int) 13 | func importantButtonClicked(index: Int) 14 | } 15 | 16 | 17 | 18 | class ToDoTableViewCell: UITableViewCell { 19 | 20 | let backGroundView = UIView() 21 | let titleLabel = UILabel() 22 | let subTitlelabel = UILabel() 23 | let completedButton = UIButton() 24 | let importantButton = UIButton() 25 | let sheduleIcon = UIImageView() 26 | 27 | var index : Int! 28 | weak var delegate : ToDoTVCDelegate? 29 | 30 | 31 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { 32 | super.init(style: style, reuseIdentifier: reuseIdentifier) 33 | prepareTableViewCell() 34 | } 35 | 36 | required init?(coder: NSCoder) { 37 | fatalError("init(coder:) has not been implemented") 38 | } 39 | 40 | func prepareTableViewCell() { 41 | 42 | // prepare Background 43 | backgroundColor = .clear 44 | selectionStyle = .none 45 | contentView.backgroundColor = .clear 46 | contentView.superview?.backgroundColor = .clear 47 | contentView.prepareHeight(constant: 60) 48 | contentView.addSubview(backGroundView) 49 | 50 | backGroundView.prepareLayout(.leading,constant: 10) 51 | backGroundView.prepareLayout(.trailing,constant: -10) 52 | backGroundView.prepareLayout(.top,constant: 10) 53 | backGroundView.prepareLayout(.bottom) 54 | backGroundView.cornerRadius(color: .lightGray) 55 | 56 | // prepare completedButton 57 | backGroundView.addSubview(completedButton) 58 | completedButton.prepareLayout(.leading,constant: 15) 59 | completedButton.prepareLayout(.top,constant: 10) 60 | completedButton.prepareHeight(constant: 30) 61 | completedButton.prepareWidth(constant: 30) 62 | completedButton.setImage(name: .Complete) 63 | completedButton.addTarget(self, action: #selector(completeTapped), 64 | for: .touchUpInside) 65 | 66 | // prepare importantButton 67 | backGroundView.addSubview(importantButton) 68 | importantButton.prepareLayout(.trailing, constant: -15) 69 | importantButton.prepareLayout(.top,constant: 10) 70 | importantButton.prepareHeight(constant: 30) 71 | importantButton.prepareWidth(constant: 30) 72 | importantButton.setImage(name: .Important) 73 | importantButton.addTarget(self, 74 | action: #selector(importantTapped), 75 | for: .touchUpInside) 76 | 77 | // prepare Title label 78 | backGroundView.addSubview(titleLabel) 79 | titleLabel.prepareLayout(.leading,constant: 60) 80 | titleLabel.prepareLayout(.top,constant: 8) 81 | titleLabel.prepareLayout(.trailing,constant: -60) 82 | titleLabel.prepareTextField(size: .title) 83 | 84 | // prepare Title label 85 | backGroundView.addSubview(sheduleIcon) 86 | sheduleIcon.prepareLayout(.leading,constant: 60) 87 | sheduleIcon.prepareLayout(.bottom,constant: -8) 88 | sheduleIcon.prepareHeight(constant: 10) 89 | sheduleIcon.prepareWidth(constant: 10) 90 | sheduleIcon.image = UIImage(named: AppButton.Shedule.imageName()) 91 | 92 | // prepare Title label 93 | backGroundView.addSubview(subTitlelabel) 94 | subTitlelabel.prepareLayout(.leading,constant: 80) 95 | subTitlelabel.prepareLayout(.bottom,constant: -8) 96 | subTitlelabel.prepareLayout(.trailing,constant: -60) 97 | subTitlelabel.prepareTextField(size: .subtite) 98 | } 99 | 100 | func prepareData(todoItem: ToDoModel,index: Int){ 101 | self.index = index 102 | titleLabel.text = todoItem.title 103 | if todoItem.isDone { titleLabel.strikeThrough() } 104 | subTitlelabel.text = todoItem.sheduleTime.time() 105 | subTitlelabel.isHidden = !todoItem.isSheduled 106 | sheduleIcon.isHidden = !todoItem.isSheduled 107 | completedButton.changeState(button: .Complete, isEnable: !todoItem.isDone) 108 | importantButton.changeState(button: .Important,isEnable: !todoItem.isImportant) 109 | } 110 | 111 | @objc func completeTapped() { 112 | delegate?.completeButtonClicked(index: index) 113 | } 114 | 115 | @objc func importantTapped() { 116 | delegate?.importantButtonClicked(index: index) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /ToDo/Views/ViewControllers/TaskDetailsVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ItemDetailsVC.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | protocol DetailsVCDelegate: AnyObject { 11 | func saveChanges(item: ToDoModel) 12 | func delete(item: ToDoModel) 13 | } 14 | 15 | 16 | class TaskDetailsVC: UIViewController{ 17 | 18 | 19 | // MARK: - Properties 20 | let backgroundView = UIView() 21 | let createdLabel = UILabel() 22 | let sheduleLabel = UILabel() 23 | let lastEditedLabel = UILabel() 24 | let titleText = TextField() 25 | let datePicker = UIDatePicker() 26 | let deletebutton = UIButton() 27 | let sheduleButton = UIButton() 28 | let completedButton = UIButton() 29 | let importantButton = UIButton() 30 | 31 | var isDeletePressed = false 32 | var todoItem: ToDoModel! 33 | weak var delegate:DetailsVCDelegate? 34 | 35 | 36 | // MARK: - Methods 37 | override func viewDidLoad() { 38 | prepareView() 39 | prepareData() 40 | } 41 | 42 | override func viewWillDisappear(_ animated: Bool) { 43 | // call delegate when user wants to get back or delete the task 44 | if isDeletePressed { 45 | delegate?.delete(item: todoItem) 46 | } else { 47 | delegate?.saveChanges(item: todoItem) 48 | } 49 | } 50 | 51 | 52 | private func prepareView() { 53 | // Prepare Ui properties Constraints and positions 54 | 55 | 56 | // prepare ListTable 57 | view.addSubview(backgroundView) 58 | backgroundView.prepareLayout(.top) 59 | backgroundView.prepareLayout(.bottom) 60 | backgroundView.prepareLayout(.leading) 61 | backgroundView.prepareLayout(.trailing) 62 | backgroundView.backgroundColor = .white 63 | navigationController?.navigationBar.tintColor = .black 64 | navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black] 65 | 66 | // prepare ListTable 67 | backgroundView.addSubview(deletebutton) 68 | deletebutton.prepareLayout(.bottom,constant: -20) 69 | deletebutton.prepareLayout(.leading,constant: 10) 70 | deletebutton.prepareLayout(.trailing,constant: -10) 71 | deletebutton.prepareHeight(constant: 60) 72 | deletebutton.backgroundColor = .black 73 | deletebutton.cornerRadius(color: .lightGray) 74 | deletebutton.setTitle(.deleteTask) 75 | deletebutton.addTarget(self, action: #selector(deletePressed), 76 | for: .touchUpInside) 77 | 78 | 79 | // prepare ListTable 80 | backgroundView.addSubview(titleText) 81 | titleText.prepareLayout(.top,constant: topbarHeight() + 10) 82 | titleText.prepareLayout(.leading,constant: 10) 83 | titleText.prepareLayout(.trailing,constant: -10) 84 | titleText.prepareHeight(constant: 40) 85 | titleText.cornerRadius(color: .black) 86 | titleText.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged) 87 | 88 | backgroundView.addSubview(importantButton) 89 | importantButton.prepareLayout(.trailing, constant: -15) 90 | importantButton.prepareLayout(.top,toItem: titleText,constant: 20) 91 | importantButton.prepareHeight(constant: 30) 92 | importantButton.prepareWidth(constant: 30) 93 | importantButton.addTarget(self, action: #selector(importantPressed), 94 | for: .touchUpInside) 95 | 96 | backgroundView.addSubview(completedButton) 97 | completedButton.prepareLayout(.trailing, constant: -15) 98 | completedButton.prepareLayout(.top,toItem: importantButton,constant: 20) 99 | completedButton.prepareHeight(constant: 30) 100 | completedButton.prepareWidth(constant: 30) 101 | completedButton.addTarget(self, action: #selector(completePressed), 102 | for: .touchUpInside) 103 | 104 | backgroundView.addSubview(sheduleButton) 105 | sheduleButton.prepareLayout(.trailing, constant: -15) 106 | sheduleButton.prepareLayout(.top,toItem: completedButton,constant: 20) 107 | sheduleButton.prepareHeight(constant: 35) 108 | sheduleButton.prepareWidth(constant: 35) 109 | sheduleButton.addTarget(self, action: #selector(sheduleIconPressed), 110 | for: .touchUpInside) 111 | 112 | // prepare Title label 113 | backgroundView.addSubview(createdLabel) 114 | createdLabel.prepareLayout(.leading,constant: 15) 115 | createdLabel.prepareLayout(.top,toItem: titleText,constant: 30) 116 | createdLabel.prepareTextField(size: .title) 117 | 118 | // prepare Title label 119 | backgroundView.addSubview(lastEditedLabel) 120 | lastEditedLabel.prepareLayout(.top,toItem: createdLabel,constant: 30) 121 | lastEditedLabel.prepareLayout(.leading,constant: 15) 122 | lastEditedLabel.prepareTextField(size: .title) 123 | 124 | // Date 125 | backgroundView.addSubview(datePicker) 126 | datePicker.locale = .current 127 | datePicker.datePickerMode = .dateAndTime 128 | datePicker.addTarget(self, action: #selector(timeChanged), for: .valueChanged) 129 | datePicker.prepareLayout(.leading,constant: 10) 130 | datePicker.prepareLayout(.top,toItem: lastEditedLabel,constant: 30) 131 | } 132 | 133 | 134 | func prepareData() { 135 | // prepare Data of Details Screen and Ui Properties 136 | 137 | guard let data = todoItem else { return } 138 | 139 | // show title screen when task name less than 5 character 140 | title = data.title.count > 5 ? "\(String(data.title.prefix(5)))..." : String(data.title.prefix(5)) 141 | datePicker.date = data.sheduleTime 142 | titleText.text = data.title 143 | 144 | completedButton.changeState(button: .Complete,isEnable: !data.isDone) 145 | importantButton.changeState(button: .Important,isEnable: !data.isImportant) 146 | sheduleButton.changeState(button: .Shedule,isEnable: !data.isSheduled) 147 | 148 | createdLabel.text = "Creadted " + data.createdTime.time() 149 | lastEditedLabel.text = "Last Edited " + data.lastEditedTime.time() 150 | } 151 | 152 | 153 | @objc func textFieldDidChange(textField: UITextField){ 154 | // change task name when editing textUI 155 | guard let text = titleText.text,!text.isEmpty else { return } 156 | todoItem.title = text 157 | } 158 | 159 | @objc func importantPressed(){ 160 | // change Task state Prioritize and text UI 161 | todoItem.isImportant = !todoItem.isImportant 162 | importantButton.changeState(button: .Important, 163 | isEnable: !todoItem.isImportant) 164 | } 165 | 166 | @objc func deletePressed(){ 167 | // assign closing state when user delete the task and get back to previous screen 168 | isDeletePressed = true 169 | navigationController?.popViewController(animated: true) 170 | } 171 | 172 | @objc func completePressed(){ 173 | // change Task state complete and text UI 174 | todoItem.isDone = !todoItem.isDone 175 | completedButton.changeState(button: .Complete, 176 | isEnable: !todoItem.isDone) 177 | titleText.isEnabled = !todoItem.isDone 178 | titleText.strikeThrough(enable: todoItem.isDone) 179 | 180 | } 181 | 182 | @objc func timeChanged(_ sender: UIDatePicker) { 183 | // Get the selcted time from date picker when user changing date and time 184 | todoItem.sheduleTime = sender.date 185 | todoItem.isSheduled = true 186 | sheduleButton.changeState(button: .Shedule, 187 | isEnable: false) 188 | } 189 | 190 | 191 | // MARK: - When user Enable and disable Shedule Task 192 | @objc func sheduleIconPressed(){ 193 | 194 | if !todoItem.isSheduled { 195 | // assign Shedule time as one hour extra from current 196 | todoItem.sheduleTime = Calendar.current.date(byAdding: .hour, 197 | value: 1, 198 | to: Date())! 199 | datePicker.setDate(todoItem.sheduleTime, animated: true) 200 | 201 | } else { 202 | // assign Shedule time as created time when State Off 203 | todoItem.sheduleTime = todoItem.createdTime 204 | } 205 | 206 | // changing task shedule State On/Off 207 | sheduleButton.changeState(button: .Shedule, isEnable: todoItem.isSheduled) 208 | todoItem.isSheduled = !todoItem.isSheduled 209 | } 210 | 211 | 212 | // MARK: - To get the height of Navigation bar to assign title top spacing 213 | func topbarHeight() -> CGFloat { 214 | return UIApplication.shared.statusBarFrame.height + navigationController!.navigationBar.frame.height 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /ToDo/Views/ViewControllers/ToDoListVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToDoListVC.swift 3 | // ToDo 4 | // 5 | // Created by Godwin on 30/12/20. 6 | // 7 | 8 | import UIKit 9 | 10 | class ToDoListVC: UIViewController { 11 | 12 | // MARK: - Properties 13 | var todolistTableView = UITableView() 14 | var addTaskButton = UIButton() 15 | var todoListVM = TodosListVM() 16 | 17 | // MARK: - Methods 18 | override func viewWillAppear(_ animated: Bool) { 19 | prepareView() 20 | reloadTable() 21 | } 22 | 23 | private func prepareView() { 24 | // Prepare Ui properties Constraints and positions 25 | let barButton = UIBarButtonItem(title: "Sort", 26 | style: .plain, 27 | target: self, 28 | action: #selector(sortTapped)) 29 | 30 | navigationItem.rightBarButtonItem = barButton 31 | prepareBarButton() 32 | todoListVM.delegate = self 33 | 34 | // prepare ListTable 35 | view.addSubview(todolistTableView) 36 | todolistTableView.prepareLayout(.top) 37 | todolistTableView.prepareLayout(.bottom,constant: -80) 38 | todolistTableView.prepareLayout(.leading) 39 | todolistTableView.prepareLayout(.trailing) 40 | todolistTableView.registerCell() 41 | todolistTableView.delegate = self 42 | todolistTableView.dataSource = self 43 | todolistTableView.separatorStyle = .none 44 | 45 | // prepare ListTable 46 | view.addSubview(addTaskButton) 47 | addTaskButton.prepareLayout(.bottom,constant: -20) 48 | addTaskButton.prepareLayout(.leading,constant: 10) 49 | addTaskButton.prepareLayout(.trailing,constant: -10) 50 | addTaskButton.prepareHeight(constant: 60) 51 | addTaskButton.backgroundColor = .black 52 | addTaskButton.cornerRadius(color: .lightGray) 53 | addTaskButton.setTitle(.addNew) 54 | addTaskButton.addTarget(self, action: #selector(addTaskAction), 55 | for: .touchUpInside) 56 | } 57 | 58 | 59 | 60 | @objc func sortTapped() { 61 | 62 | // action when user clicking category tasks 63 | if todoListVM.canSort { 64 | 65 | // showing alert when tasks are less than two count 66 | let alert = UIAlertController(title: "List Empty", message: "Add more than one tasks to catgories tasks", preferredStyle: UIAlertController.Style.alert) 67 | 68 | let addNew = UIAlertAction(title: "Add New", style: .default, handler: { (action: UIAlertAction!) in 69 | self.addTaskAction() 70 | }) 71 | addNew.prepare() 72 | let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in }) 73 | cancel.prepare(color: .red) 74 | 75 | alert.addAction(addNew) 76 | alert.addAction(cancel) 77 | present(alert, animated: true, completion: nil) 78 | return 79 | } 80 | 81 | // showing choices of categories tasks by user Input 82 | 83 | let actionSheetController = UIAlertController(title: "Select Category", 84 | message: "Sorting List Items by Selected Category", 85 | preferredStyle: .actionSheet) 86 | 87 | 88 | for category in todoListVM.sortCategories { 89 | let style : UIAlertAction.Style = category == .Default ? .cancel : .default 90 | let action = UIAlertAction(title: category.rawValue, 91 | style:style ) { action -> Void in 92 | guard category != .Default else { return } 93 | self.todoListVM.sortList(by: category) 94 | } 95 | action.prepare() 96 | actionSheetController.addAction(action) 97 | } 98 | 99 | actionSheetController.popoverPresentationController?.sourceView = todolistTableView 100 | 101 | present(actionSheetController, animated: true) 102 | } 103 | 104 | @objc func addTaskAction() { 105 | 106 | // showing floating text field to get the name of the task 107 | let ac = UIAlertController(title: "Task Name", 108 | message: nil, 109 | preferredStyle: .alert) 110 | ac.addTextField() 111 | 112 | let submitAction = UIAlertAction(title: "Add", style: .default) { [unowned ac] _ in 113 | guard let text = ac.textFields![0].text,!text.isEmpty else { 114 | return 115 | } 116 | self.todoListVM.addNew(text: text) 117 | self.reloadTable() 118 | } 119 | submitAction.setValue(UIColor.black, forKey: "titleTextColor") 120 | ac.addAction(submitAction) 121 | present(ac, animated: true) 122 | } 123 | 124 | func reloadTable(animation: Bool = true){ 125 | 126 | // changing category input button title whenever user reloading table while current checking sorting stype 127 | if todoListVM.sortType != .Default{ 128 | navigationItem.rightBarButtonItem?.title = "Category - " + todoListVM.sortType.rawValue 129 | } else { 130 | navigationItem.rightBarButtonItem?.title = "Category" 131 | } 132 | 133 | // reloading ToDo items list table when user changing state of tasks prperties 134 | guard animation else { 135 | // without animation 136 | todolistTableView.reloadData() 137 | return 138 | } 139 | // with animation 140 | UIView.transition(with: todolistTableView, 141 | duration: 0.5, 142 | options: .transitionCrossDissolve, 143 | animations: { self.todolistTableView.reloadData() }) 144 | } 145 | } 146 | 147 | 148 | extension ToDoListVC: UITableViewDelegate,UITableViewDataSource { 149 | 150 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 151 | todoListVM.count 152 | } 153 | 154 | func tableView(_ tableView: UITableView, 155 | cellForRowAt indexPath: IndexPath) -> UITableViewCell { 156 | let todoItemTVC = ToDoTableViewCell() 157 | todoItemTVC.delegate = self 158 | todoItemTVC.prepareData(todoItem: todoListVM.items[indexPath.row], index: indexPath.row) 159 | return todoItemTVC 160 | } 161 | 162 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 163 | let vc = TaskDetailsVC() 164 | vc.todoItem = todoListVM.prepareDetails(index: indexPath.row) 165 | vc.delegate = self 166 | navigationController?.pushViewController(vc, animated: true) 167 | } 168 | } 169 | 170 | 171 | extension ToDoListVC: ToDoTVCDelegate { 172 | func completeButtonClicked(index: Int) { 173 | todoListVM.makeComplete(index: index) 174 | reloadTable() 175 | } 176 | 177 | func importantButtonClicked(index: Int) { 178 | todoListVM.makeImportant(index: index) 179 | reloadTable() 180 | } 181 | } 182 | 183 | 184 | extension ToDoListVC: TodosListDelegate { 185 | func reloadData() { 186 | reloadTable(animation: false) 187 | } 188 | } 189 | 190 | 191 | extension ToDoListVC: DetailsVCDelegate { 192 | 193 | func delete(item: ToDoModel) { 194 | guard let index = item.index else { return } 195 | todoListVM.items.remove(at: index) 196 | reloadTable(animation: false) 197 | } 198 | 199 | func saveChanges(item: ToDoModel) { 200 | guard let index = item.index else { return } 201 | todoListVM.items[index].saveChanges(of: item) 202 | reloadTable() 203 | } 204 | } 205 | --------------------------------------------------------------------------------