领域数据未在表视图中显示

时间:2016-02-19 19:46:22

标签: ios swift realm

对于尝试使用Realm开发简单笔记应用程序的iOS,我相对较新。我有几个视图控制器。

创建新笔记:

//
//  ViewController.swift
//  Note It
//
//  Created by James Parsons on 2/19/16.
//  Copyright © 2016 James Parsons. All rights reserved.
//

import UIKit
import RealmSwift
import Realm

class NewNoteViewController: UIViewController {
    // MARK: - Properties
    var save: Bool?
    var realm: Realm?

    // MARK: - Outlets
    @IBOutlet weak var txtView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Initialize realm.
        realm = try! Realm()

        // Set up insets.
        txtView.contentInset = UIEdgeInsetsMake(-50, 10, 0, 0)

        // Do we have any data from the last time?
        let data: String? = NSUserDefaults.standardUserDefaults().objectForKey("lastNoteData") as? String

        if (data != nil) {
            txtView.text = data
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillDisappear(animated: Bool) {
        // Do we want to save the data?
        if save! {
            if txtView.hasText() {
                // Save the current note data
                let noteData = txtView.text
                NSUserDefaults.standardUserDefaults().setValue(noteData, forKey: "lastNoteData")
            }
        } else {
            // No need to save note data. Clear the setting.
            NSUserDefaults.standardUserDefaults().setValue(nil, forKey: "lastNoteData")
        }

    }

    // MARK: - Actions
    @IBAction func btnCancel(sender: UIBarButtonItem) {
        // Save note content
        save = true
        self.navigationController!.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
    }

    @IBAction func btnSave(sender: UIBarButtonItem) {
        var alert: UIAlertController

        if txtView.hasText() {
            let textToSerialize = txtView.text

            alert = UIAlertController(title: "Save", message: "Enter a name for this note", preferredStyle: .Alert)

            let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
            let saveAction = UIAlertAction(title: "Save", style: .Default, handler: { (action: UIAlertAction) -> Void in
                // DEBUG: See if this is firing.
                // By the way it works.
                print("Yay, it worked")

                // Don't serialize data.
                self.save = false

                // Get the note name.
                let name = alert.textFields!.first!.text!

                // Build the note.
                let noteToSave = Note(name: name, content: textToSerialize, date: NSDate())

                // Save the note into Realm.
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    try! self.realm!.write {
                        self.realm!.add(noteToSave)
                    }
                })

                // Go back.
                self.navigationController!.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
            })

            alert.addTextFieldWithConfigurationHandler {
                (textField: UITextField) -> Void in
            }

            alert.addAction(cancelAction)
            alert.addAction(saveAction)

            presentViewController(alert, animated: true, completion: nil)
        } else {
            // Notes cannot be blank.
            let alert = UIAlertController(title: "Whoops", message: "This note needs some content", preferredStyle: .Alert)

            let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
            alert.addAction(okAction)

            // Show the alert.
            presentViewController(alert, animated: true, completion: nil)

        }
    }
}

主视图:

//
//  NotesViewController.swift
//  Note It
//
//  Created by James Parsons on 2/19/16.
//  Copyright © 2016 James Parsons. All rights reserved.
//

import UIKit
import RealmSwift
import Realm

class NotesViewController: UITableViewController {
    // MARK: - Properties
    var notes: Results<Note>?
    var realm: Realm?

    // MARK: ViewController methods.
    override func viewDidLoad() {
        super.viewDidLoad()

        // Refresh the table.
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.tableView.reloadData()
        })

        // Set up our Realm.
        realm = try! Realm()

        // Get all the notes.
        notes = realm!.objects(Note)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return number of objects.
        return realm!.objects(Note).count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("note", forIndexPath: indexPath)

        // Set up the cell with our data
        if let note = notes?[indexPath.row] {
            cell.textLabel!.text = note.name
            cell.detailTextLabel!.text = dateToString(note.dateCreated)
        }

        return cell
    }


    /*
    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */

    /*
    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */

    // MARK: - Functions
    func dateToString(date: NSDate) -> String {
        let formatter = NSDateFormatter()
        formatter.dateStyle = .ShortStyle

        return formatter.stringFromDate(date)

    }

}

和模型

//
//  Note.swift
//  Note It
//
//  Created by James Parsons on 2/19/16.
//  Copyright © 2016 James Parsons. All rights reserved.
//

import Foundation
import RealmSwift

// Realm model for notes.
class Note: Object {
    // MARK: - Properties
    dynamic var name = ""
    dynamic var content = ""
    dynamic var dateCreated = NSDate()

    // MARK: - Intializers
    required init() {
        super.init()
    }

    required init(name: String, content: String, date: NSDate) {
        self.name = name
        self.content = content
        self.dateCreated = date

        super.init()
    }

}

我知道保存操作的处理程序触发,但表中没有显示任何数据。我做错了什么?

1 个答案:

答案 0 :(得分:1)

您需要的代码会在您添加注释时告知您的tableview更新。有许多方法可以解决这个问题。

一种可能的方法是使用领域通知功能。

首先将以下变量添加到NotesViewController:

var token: NotificationToken?

在NotesViewController的viewDidLoad中添加:

// Get all the notes.
notes = realm!.objects(Note)

token = notes!.addNotificationBlock({ (notification, realm) -> Void in
    self.tableView.reloadData()
})

我对领域并不完全熟悉,但您可能还需要添加一个删除此标记的deinit实现:

deinit {
    if let t = token {
        t.stop()
    }
}

编辑考虑到bdash的评论