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
14 changes: 11 additions & 3 deletions MyLog/LogItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ import Foundation
import CoreData

class LogItem: NSManagedObject {

@NSManaged var itemText: String
@NSManaged var title: String

}

class func createInManagedObjectContext(moc: NSManagedObjectContext, title: String, text: String) -> LogItem {
let newItem = NSEntityDescription.insertNewObjectForEntityForName("LogItem", inManagedObjectContext: moc) as! LogItem
newItem.title = title
newItem.itemText = text

return newItem
}

}
191 changes: 172 additions & 19 deletions MyLog/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,194 @@
import UIKit
import CoreData

class ViewController: UIViewController {
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

// Create an empty array of LogItem's
var logItems = [LogItem]()

// Retreive the managedObjectContext from AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

// Create the table view as soon as this class loads
var logTableView = UITableView(frame: CGRectZero, style: .Plain)

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

let newItem = NSEntityDescription.insertNewObjectForEntityForName("LogItem", inManagedObjectContext: self.managedObjectContext!) as! LogItem

newItem.title = "Wrote Core Data Tutorial"
newItem.itemText = "Wrote and post a tutorial on the basics of Core Data to blog."

// Use optional binding to confirm the managedObjectContext
if let moc = self.managedObjectContext {

// Create some dummy data to work with
var items = [
("Best Animal", "Dog"),
("Best Language", "Swift"),
("Worst Animal", "Cthulu"),
("Worst Language", "LOLCODE")
]

// Loop through, creating items
for (itemTitle, itemText) in items {
// Create an individual item
LogItem.createInManagedObjectContext(moc,
title: itemTitle, text: itemText)
}


// Now that the view loaded, we have a frame for the view, which will be (0,0,screen width, screen height)
// This is a good size for the table view as well, so let's use that
// The only adjust we'll make is to move it down by 20 pixels, and reduce the size by 20 pixels
// in order to account for the status bar

// Store the full frame in a temporary variable
var viewFrame = self.view.frame

// Adjust it down by 20 points
viewFrame.origin.y += 20

// Add in the "+" button at the bottom
let addButton = UIButton(frame: CGRectMake(0, UIScreen.mainScreen().bounds.size.height - 44, UIScreen.mainScreen().bounds.size.width, 44))
addButton.setTitle("+", forState: .Normal)
addButton.backgroundColor = UIColor(red: 0.5, green: 0.9, blue: 0.5, alpha: 1.0)
addButton.addTarget(self, action: "addNewItem", forControlEvents: .TouchUpInside)
self.view.addSubview(addButton)

// Reduce the total height by 20 points for the status bar, and 44 points for the bottom button
viewFrame.size.height -= (20 + addButton.frame.size.height)

// Set the logTableview's frame to equal our temporary variable with the full size of the view
// adjusted to account for the status bar height
logTableView.frame = viewFrame

// Add the table view to this view controller's view
self.view.addSubview(logTableView)

// Here, we tell the table view that we intend to use a cell we're going to call "LogCell"
// This will be associated with the standard UITableViewCell class for now
logTableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "LogCell")

// This tells the table view that it should get it's data from this class, ViewController
logTableView.dataSource = self
logTableView.delegate = self

}
fetchLog()
}

let addItemAlertViewTag = 0
let addItemTextAlertViewTag = 1
func addNewItem() {

var titlePrompt = UIAlertController(title: "Enter Title",
message: "Enter Text",
preferredStyle: .Alert)

var titleTextField: UITextField?
titlePrompt.addTextFieldWithConfigurationHandler {
(textField) -> Void in
titleTextField = textField
textField.placeholder = "Title"
}

titlePrompt.addAction(UIAlertAction(title: "Ok",
style: .Default,
handler: { (action) -> Void in
if let textField = titleTextField {
self.saveNewItem(textField.text)
}
}))

self.presentViewController(titlePrompt,
animated: true,
completion: nil)
}

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
func saveNewItem(title : String) {
// Create the new log item
var newLogItem = LogItem.createInManagedObjectContext(self.managedObjectContext!, title: title, text: "")

// Create a new fetch request using the LogItem entity
// Update the array containing the table view row data
self.fetchLog()

// Animate in the new row
// Use Swift's find() function to figure out the index of the newLogItem
// after it's been added and sorted in our logItems array
if let newItemIndex = find(logItems, newLogItem) {
// Create an NSIndexPath from the newItemIndex
let newLogItemIndexPath = NSIndexPath(forRow: newItemIndex, inSection: 0)
// Animate in the insertion of this row
logTableView.insertRowsAtIndexPaths([ newLogItemIndexPath ], withRowAnimation: .Automatic)
save()
}
}

func save() {
var error : NSError?
if(managedObjectContext!.save(&error) ) {
println(error?.localizedDescription)
}
}

func fetchLog() {
let fetchRequest = NSFetchRequest(entityName: "LogItem")

// Execute the fetch request, and cast the results to an array of LogItem objects
// Create a sort descriptor object that sorts on the "title"
// property of the Core Data object
let sortDescriptor = NSSortDescriptor(key: "title", ascending: true)

// Set the list of sort descriptors in the fetch request,
// so it includes the sort descriptor
fetchRequest.sortDescriptors = [sortDescriptor]

if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [LogItem] {
logItems = fetchResults
}
}

// MARK: UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// How many rows are there in this section?
// There's only 1 section, and it has a number of rows
// equal to the number of logItems, so return the count
return logItems.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("LogCell") as! UITableViewCell

// Get the LogItem for this index
let logItem = logItems[indexPath.row]

// Set the title of the cell to be the title of the logItem
cell.textLabel?.text = logItem.title
return cell
}

// MARK: UITableViewDelegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let logItem = logItems[indexPath.row]
println(logItem.itemText)
}

func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if(editingStyle == .Delete ) {
// Find the LogItem object the user is trying to delete
let logItemToDelete = logItems[indexPath.row]

// Create an Alert, and set it's message to whatever the itemText is
let alert = UIAlertController(title: fetchResults[0].title,
message: fetchResults[0].itemText,
preferredStyle: .Alert)
// Delete it from the managedObjectContext
managedObjectContext?.deleteObject(logItemToDelete)

// Display the alert
self.presentViewController(alert,
animated: true,
completion: nil)
// Refresh the table view to indicate that it's deleted
self.fetchLog()

// Tell the table view to animate out that row
logTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)

save()
}
}

Expand All @@ -51,6 +205,5 @@ class ViewController: UIViewController {
// Dispose of any resources that can be recreated.
}


}