在我正在进行的项目中,我有一个注释函数,它充当练习/训练日志。此培训日志由5个文件组成:Note.swift,NotesTableViewController.swift,NoteDetailViewController.swift,NoteDetailTableViewCell.swift和NoteStore.swift。该表的类是NotesTableViewController,它是一个带有UITableViewDelegate的UIViewController和UITableViewDataSource。此笔记功能正常工作,填充tableview,但无法从.plist文件中删除注释,并在重新打开应用程序时继续检索它。我不知道这是否真的无法保存/加载,或者其他地方是否出现问题。我会感激任何帮助。文件如下:
Note.swift
import Foundation
class Note : NSObject, NSCoding {
var title = ""
var text = ""
var date = NSDate() // Defaults to current date / time
// Computed property to return date as a string
var shortDate : NSString {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM/dd/yy"
return dateFormatter.stringFromDate(self.date)
}
override init() {
super.init()
}
// 1: Encode ourselves...
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(title, forKey: "title")
aCoder.encodeObject(text, forKey: "text")
aCoder.encodeObject(date, forKey: "date")
}
// 2: Decode ourselves on init
required init(coder aDecoder: NSCoder) {
self.title = aDecoder.decodeObjectForKey("title") as! String
self.text = aDecoder.decodeObjectForKey("text") as! String
self.date = aDecoder.decodeObjectForKey("date") as! NSDate
}
}
NotesTableViewController.swift
import UIKit
class NotesTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var OpenButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
// Leverage the built in TableViewController Edit button
self.navigationItem.leftBarButtonItem = self.editButtonItem()
OpenButton.target = self.revealViewController()
OpenButton.action = Selector("revealToggle:")
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.tableView.reloadData()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// ensure we are not in edit mode
editing = false
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Here we pass the note they tapped on between the view controllers
if segue.identifier == "NoteDetailPush" {
// Get the controller we are going to
var noteDetail = segue.destinationViewController as! NoteDetailViewController
// Lookup the data we want to pass
var theCell = sender as! NoteDetailTableViewCell
// Pass the data forward
noteDetail.theNote = theCell.theNote
}
}
@IBAction func saveFromNoteDetail(segue:UIStoryboardSegue) {
// We come here from an exit segue when they hit save on the detail screen
// Get the controller we are coming from
var noteDetail = segue.sourceViewController as! NoteDetailViewController
// If there is a row selected....
if let indexPath = tableView.indexPathForSelectedRow() {
// Update note in our store
NoteStore.sharedNoteStore.updateNote(theNote: noteDetail.theNote)
// The user was in edit mode
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
} else {
// Otherwise, add a new record
NoteStore.sharedNoteStore.createNote(theNote: noteDetail.theNote)
// Get an index to insert the row at
var indexPath = NSIndexPath(forRow: NoteStore.sharedNoteStore.count()-1, inSection: 0)
// Update tableview
tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
// MARK: - Table view data source
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Just return the note count
return NoteStore.sharedNoteStore.count()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Fetch a reusable cell
let cell = tableView.dequeueReusableCellWithIdentifier("NoteDetailTableViewCell", forIndexPath: indexPath) as! NoteDetailTableViewCell
// Fetch the note
var rowNumber = indexPath.row
var theNote = NoteStore.sharedNoteStore.getNote(rowNumber)
// Configure the cell
cell.setupCell(theNote)
return cell
}
// Override to support editing the table view.
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
NoteStore.sharedNoteStore.deleteNote(indexPath.row)
// Delete the note from the tableview
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}
}
NoteDetailViewController
import UIKit
class NoteDetailViewController: UIViewController {
var theNote = Note()
@IBOutlet weak var noteTitleLabel: UITextField!
@IBOutlet weak var noteTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// The view starts here. By now we either have a note to edit
// or we have a blank note in theNote property we can use
// Update the screen with the contents of theNote
self.noteTitleLabel.text = theNote.title
self.noteTextView.text = theNote.text
// Set the Cursor in the note text area
self.noteTextView.becomeFirstResponder()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Whenever we leave the screen, update our note model
theNote.title = self.noteTitleLabel.text
theNote.text = self.noteTextView.text
}
@IBAction func CancelNote(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
NoteDetailTableViewCell
import UIKit
class NoteDetailTableViewCell : UITableViewCell {
// The note currently being shown
weak var theNote : Note!
// Interface builder outlets
@IBOutlet weak var noteTitleLabel : UILabel!
@IBOutlet weak var noteDateLabel : UILabel!
@IBOutlet weak var noteTextLabel : UILabel!
// Insert note contents into the cell
func setupCell(theNote:Note) {
// Save a weak reference to the note
self.theNote = theNote
// Update the cell
noteTitleLabel.text = theNote.title
noteTextLabel.text = theNote.text
noteDateLabel.text = theNote.shortDate as String
}
}
最后,NoteStore
import Foundation
class NoteStore {
// Mark: Singleton Pattern (hacked since we don't have class var's yet)
class var sharedNoteStore : NoteStore {
struct Static {
static let instance : NoteStore = NoteStore()
}
return Static.instance
}
// Private init to force usage of singleton
private init() {
load()
}
// Array to hold our notes
private var notes : [Note]!
// CRUD - Create, Read, Update, Delete
// Create
func createNote(theNote:Note = Note()) -> Note {
notes.append(theNote)
return theNote
}
// Read
func getNote(index:Int) -> Note {
return notes[index]
}
// Update
func updateNote(#theNote:Note) {
// Notes passed by reference, no update code needed
}
// Delete
func deleteNote(index:Int) {
notes.removeAtIndex(index)
}
func deleteNote(withNote:Note) {
for (i, note) in enumerate(notes) {
if note === withNote {
notes.removeAtIndex(i)
return
}
}
}
// Count
func count() -> Int {
return notes.count
}
// Mark: Persistence
// 1: Find the file & directory we want to save to...
func archiveFilePath() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths.first as! NSString
let path = documentsDirectory.stringByAppendingPathComponent("NoteStore.plist")
return path
}
// 2: Do the save to disk.....
func save() {
NSKeyedArchiver.archiveRootObject(notes, toFile: archiveFilePath())
}
// 3: Do the reload from disk....
func load() {
let filePath = archiveFilePath()
let fileManager = NSFileManager.defaultManager()
if fileManager.fileExistsAtPath(filePath) {
notes = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! [Note]
} else {
notes = [Note]()
}
}
}
答案 0 :(得分:1)
它看起来像你在更改创建,删除或更新笔记后没有调用保存方法
你可以添加例如:
func deleteNote(index:Int) {
notes.removeAtIndex(index)
save()
}
如果您不想在每次更改后编写新的plist,请在vievWillDisappear上调用保存方法