Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Task/Task.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
objects = {

/* Begin PBXBuildFile section */
DE738E6B2492D91900C27A4F /* TaskDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE738E6A2492D91900C27A4F /* TaskDetailTableViewController.swift */; };
DE738E6D2492D95E00C27A4F /* CoreDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE738E6C2492D95E00C27A4F /* CoreDataStack.swift */; };
DE738E6F2492DAC000C27A4F /* Task+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE738E6E2492DAC000C27A4F /* Task+Convenience.swift */; };
DE738E712492DBF400C27A4F /* TaskController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE738E702492DBF400C27A4F /* TaskController.swift */; };
DE738E7324930A5900C27A4F /* DateHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE738E7224930A5900C27A4F /* DateHelpers.swift */; };
DE738E7524931A3000C27A4F /* ButtonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE738E7424931A3000C27A4F /* ButtonTableViewCell.swift */; };
DED0EF2D2495553200C8E3A9 /* TaskListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DED0EF2C2495553200C8E3A9 /* TaskListTableViewController.swift */; };
FB4BD1A7237A1D88006648A7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB4BD1A6237A1D88006648A7 /* AppDelegate.swift */; };
FB4BD1A9237A1D88006648A7 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB4BD1A8237A1D88006648A7 /* SceneDelegate.swift */; };
FB4BD1AE237A1D88006648A7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB4BD1AC237A1D88006648A7 /* Main.storyboard */; };
Expand All @@ -16,6 +23,13 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
DE738E6A2492D91900C27A4F /* TaskDetailTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskDetailTableViewController.swift; sourceTree = "<group>"; };
DE738E6C2492D95E00C27A4F /* CoreDataStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataStack.swift; sourceTree = "<group>"; };
DE738E6E2492DAC000C27A4F /* Task+Convenience.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Task+Convenience.swift"; sourceTree = "<group>"; };
DE738E702492DBF400C27A4F /* TaskController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskController.swift; sourceTree = "<group>"; };
DE738E7224930A5900C27A4F /* DateHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateHelpers.swift; sourceTree = "<group>"; };
DE738E7424931A3000C27A4F /* ButtonTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonTableViewCell.swift; sourceTree = "<group>"; };
DED0EF2C2495553200C8E3A9 /* TaskListTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskListTableViewController.swift; sourceTree = "<group>"; };
FB4BD1A3237A1D88006648A7 /* Task.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Task.app; sourceTree = BUILT_PRODUCTS_DIR; };
FB4BD1A6237A1D88006648A7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
FB4BD1A8237A1D88006648A7 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand All @@ -37,6 +51,33 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
DE738E652492D68600C27A4F /* Controllers */ = {
isa = PBXGroup;
children = (
DE738E672492D6A600C27A4F /* ViewControllers */,
DE738E662492D69F00C27A4F /* ModelControllers */,
);
path = Controllers;
sourceTree = "<group>";
};
DE738E662492D69F00C27A4F /* ModelControllers */ = {
isa = PBXGroup;
children = (
DE738E702492DBF400C27A4F /* TaskController.swift */,
);
path = ModelControllers;
sourceTree = "<group>";
};
DE738E672492D6A600C27A4F /* ViewControllers */ = {
isa = PBXGroup;
children = (
DE738E6A2492D91900C27A4F /* TaskDetailTableViewController.swift */,
DE738E7424931A3000C27A4F /* ButtonTableViewCell.swift */,
DED0EF2C2495553200C8E3A9 /* TaskListTableViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
};
FB4BD19A237A1D88006648A7 = {
isa = PBXGroup;
children = (
Expand All @@ -56,6 +97,7 @@
FB4BD1A5237A1D88006648A7 /* Task */ = {
isa = PBXGroup;
children = (
DE738E652492D68600C27A4F /* Controllers */,
FB4BD1BE237A1E0B006648A7 /* Model */,
FB4BD1BF237A1E11006648A7 /* Storyboards */,
FB4BD1BD237A1E00006648A7 /* Resources */,
Expand All @@ -78,6 +120,9 @@
isa = PBXGroup;
children = (
FB4BD1AF237A1D88006648A7 /* Task.xcdatamodeld */,
DE738E6C2492D95E00C27A4F /* CoreDataStack.swift */,
DE738E6E2492DAC000C27A4F /* Task+Convenience.swift */,
DE738E7224930A5900C27A4F /* DateHelpers.swift */,
);
path = Model;
sourceTree = "<group>";
Expand Down Expand Up @@ -164,7 +209,14 @@
files = (
FB4BD1B1237A1D88006648A7 /* Task.xcdatamodeld in Sources */,
FB4BD1A7237A1D88006648A7 /* AppDelegate.swift in Sources */,
DE738E6F2492DAC000C27A4F /* Task+Convenience.swift in Sources */,
DE738E6D2492D95E00C27A4F /* CoreDataStack.swift in Sources */,
DED0EF2D2495553200C8E3A9 /* TaskListTableViewController.swift in Sources */,
DE738E6B2492D91900C27A4F /* TaskDetailTableViewController.swift in Sources */,
DE738E712492DBF400C27A4F /* TaskController.swift in Sources */,
DE738E7524931A3000C27A4F /* ButtonTableViewCell.swift in Sources */,
FB4BD1A9237A1D88006648A7 /* SceneDelegate.swift in Sources */,
DE738E7324930A5900C27A4F /* DateHelpers.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
73 changes: 73 additions & 0 deletions Task/Task/Controllers/ModelControllers/TaskController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// TaskController.swift
// Task
//
// Created by Connor Holland on 6/11/20.
// Copyright © 2020 Karl Pfister. All rights reserved.
//

import Foundation
import CoreData

class TaskController {

static let shared = TaskController()

//Source of truth

var fetchedResultsController: NSFetchedResultsController<Task>

init() {
let fetchedRequest: NSFetchRequest<Task> = Task.fetchRequest()

fetchedRequest.sortDescriptors = [NSSortDescriptor(key: "isComplete", ascending: true), NSSortDescriptor(key: "due", ascending: true)]



let resultsController = NSFetchedResultsController(fetchRequest: fetchedRequest, managedObjectContext: CoreDataStack.context, sectionNameKeyPath: "isComplete", cacheName: nil)
fetchedResultsController = resultsController
do {
try fetchedResultsController.performFetch()
} catch {
print(error.localizedDescription)
}
}


// MARK: - CRUD Methods

//create
func add(taskWithName name: String, notes: String?, due: Date?) {
Task(name: name, notes: notes, due: due)
saveToPersistenceStore()
}

//update
func update(task: Task, name: String, notes: String, due: Date) {
task.name = name
task.notes = notes
task.due = due
saveToPersistenceStore()
}

//delete
func delete(task: Task) {
task.managedObjectContext?.delete(task)
saveToPersistenceStore()
}

func toggleIsComplete(task: Task) {
task.isComplete = !task.isComplete
saveToPersistenceStore()
}



func saveToPersistenceStore() {
do {
try CoreDataStack.context.save()
} catch {
print("There was an error in \(#function): \(error) - \(error.localizedDescription)")
}
}
}
38 changes: 38 additions & 0 deletions Task/Task/Controllers/ViewControllers/ButtonTableViewCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ButtonTableViewCell.swift
// Task
//
// Created by Connor Holland on 6/11/20.
// Copyright © 2020 Karl Pfister. All rights reserved.
//

import UIKit

protocol ButtonTableViewCellDelegate: AnyObject {
func buttonCellButtonTapped(_ sender: ButtonTableViewCell)
}


class ButtonTableViewCell: UITableViewCell {

@IBOutlet weak var primaryLabel: UILabel!
@IBOutlet weak var completeButton: UIButton!



weak var delegate: ButtonTableViewCellDelegate?

func updateButton(_ isComplete: Bool) {
let imageName = isComplete ? "complete" : "incomplete"
completeButton.setImage(UIImage(named: imageName), for: .normal)
}

func update(withTask task: Task) {
primaryLabel.text = task.name
updateButton(task.isComplete)
}

@IBAction func completeButtonTapped(_ sender: Any) {
delegate?.buttonCellButtonTapped(self)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// TaskDetailTableViewController.swift
// Task
//
// Created by Connor Holland on 6/11/20.
// Copyright © 2020 Karl Pfister. All rights reserved.
//

import UIKit

class TaskDetailTableViewController: UITableViewController {

@IBOutlet weak var taskNameTextField: UITextField!
@IBOutlet weak var dueTextField: UITextField!
@IBOutlet weak var noteTextView: UITextView!
@IBOutlet var dueDatePicker: UIDatePicker!


var task: Task?
var dueDateValue: Date?


override func viewDidLoad() {
super.viewDidLoad()
updateViews()
dueTextField.inputView = dueDatePicker

}

//Actions
//Come back to this
@IBAction func saveButtonTapped(_ sender: Any) {
guard let name = taskNameTextField.text, !name.isEmpty, let noteText = noteTextView.text, !noteText.isEmpty, let due = dueDateValue else {return}
if let task = task {
TaskController.shared.update(task: task, name: name, notes: noteText, due: due)
} else {
TaskController.shared.add(taskWithName: name, notes: noteText, due: due)
}
navigationController?.popViewController(animated: true)
}



@IBAction func cancelButtonTapped(_ sender: Any) {
navigationController?.popViewController(animated: true)
}

@IBAction func datePickerChanged(_ sender: UIDatePicker) {
dueDateValue = dueDatePicker.date
dueTextField.text = dueDateValue?.stringValue()
}

@IBAction func userTappedView(_ sender: UITapGestureRecognizer) {
dueTextField.resignFirstResponder()
}



func updateViews() {
taskNameTextField.text = task?.name
dueTextField.text = task?.due?.stringValue()
noteTextView.text = task?.notes
self.dueDateValue = task?.due
tableView.reloadData()
}


// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 3
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}

}
Loading