数据无法加载到我的表格视图中

时间:2015-09-07 19:58:22

标签: ios database swift tableview realm

所以我的笔记应用程序有一个UITableViewController类,其中一切正常,添加,删除和编辑表视图。但现在我正在尝试使用“Realm”数据库加载数据。我是iOS(Swift)的新手,特别是Realm,所以我有点困惑。我完全保存到数据库中,当我单击导航栏中的“保存”按钮时,它会显示出来。但是当我重新启动应用程序时,表视图完全是空的。我现在已经坚持了一段时间,尝试了迄今为止所知的一切,但是无法让它显示出来。有人可以帮助我,也许可以告诉我我做错了什么,或者根本不做什么?非常感谢你。

这是我的班级

import UIKit
import Realm

class NoteTableViewController: UITableViewController {

    // MARK: Properties

    var notes = [Note]() // Initialized with a default value (an empty array of Note objects).

    override func viewDidLoad() {
        super.viewDidLoad()

        // Get Realm Database location
        println(RLMRealm.defaultRealm().path)

    }

    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 the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return notes.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "NoteTableViewCell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NoteTableViewCell

        // Fetches the appropriate note for the data source layout in the notes array
        let note = notes[indexPath.row]

        // Configure the cell...
        cell.titleLabel.text = note.title
        cell.bodyLabel.text = note.body

        return cell
    }



    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO 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
            notes.removeAtIndex(indexPath.row)

            // Get the default Realm (Will do this part later)
            /*
            let realm = RLMRealm.defaultRealm()
            realm.beginWriteTransaction()

            realm.deleteObject(notes[Int(indexPath.row)])
            realm.commitWriteTransaction()
            */

            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
        }
    }


    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "ShowDetail" { // Clicked on a cell
            let noteDetailViewController = segue.destinationViewController as! NoteViewController
            // Get the cell that generated this segue.
            if let selectedNoteCell = sender as? NoteTableViewCell {
                let indexPath = tableView.indexPathForCell(selectedNoteCell)!
                let selectedNote = notes[indexPath.row]
                noteDetailViewController.note = selectedNote
            }
        }
        else if segue.identifier == "AddItem" { // Clicked add button
            println("Adding new note")
        }
    }


    @IBAction func unwindToNoteList(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.sourceViewController as? NoteViewController, note = sourceViewController.note {
            if let selectedIndexPath = tableView.indexPathForSelectedRow() { // User clicked on a row
                // Update an existing note.
                notes[selectedIndexPath.row] = note

                tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
            }
            else {
                // Add a new note.
                let newIndexPath = NSIndexPath(forRow: notes.count, inSection: 0)
                notes.append(note)

                // Persist in database
                let realm = RLMRealm.defaultRealm()
                realm.beginWriteTransaction()
                Note.createInRealm(realm, withValue: notes[newIndexPath.row])
                realm.commitWriteTransaction()

                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
            }
        }
    }

}

这个是Note Object类

import UIKit // Automatically imports Foundation
import Realm

class Note: RLMObject {

    // MARK: Properties

    dynamic var title: String = ""
    dynamic var body: String = ""

    // MARK: Initialization

    init?(title: String, body: String) { // Failable initializer


        // Initialize stored properties.
        self.title = title
        self.body = body

        super.init()

        // Initialization should fail if there is no title
        if title.isEmpty {
            return nil
        }

    }

    // Must have for Realm to work
    override init() {
        super.init()
    }

}

经过2天以上解决后......这是我更新的课程

正如Swinny89所说的那样,并开始使用所有对象的新注释对象,而不是初始化“空”注释数组。

import UIKit
import Realm

class NoteTableViewController: UITableViewController {

  // MARK: Properties

    var notes = Note.allObjects()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Get Realm Database location
        println(RLMRealm.defaultRealm().path)

    }
    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 the number of sections.
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return Int(notes.count)
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "NoteTableViewCell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NoteTableViewCell

        let object = notes[UInt(indexPath.row)] as! Note

        // Configure the cell...
        cell.titleLabel.text = object.title
        cell.bodyLabel.text = object.body

        return cell
    }

    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return NO 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 from database
            let realm = RLMRealm.defaultRealm()
            realm.beginWriteTransaction()
            realm.deleteObject(notes[UInt(indexPath.row)] as! RLMObject)
            realm.commitWriteTransaction()

            // Delete row from table view
            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
        }
    }

    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "ShowDetail" { // Clicked on a cell
            let noteDetailViewController = segue.destinationViewController as! NoteViewController
            // Get the cell that generated this segue.
            if let selectedNoteCell = sender as? NoteTableViewCell {
                let indexPath = tableView.indexPathForCell(selectedNoteCell)!

                let selectedNote = notes[UInt(indexPath.row)] as! Note
                noteDetailViewController.note = selectedNote

            }
        }
        else if segue.identifier == "AddItem" { // Clicked add button
            println("Adding new note")
        }
    }

    @IBAction func unwindToNoteList(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.sourceViewController as? NoteViewController, note = sourceViewController.note {

            let uuid = NSUUID().UUIDString // Needed for primary key. see below

            var unwindedNote = Note()

            if let selectedIndexPath = tableView.indexPathForSelectedRow() { // User clicked on a row

                // Updating of the note is done in NoteViewController

                tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
            }
            else {
                // Add a new note.
                let newIndexPath = NSIndexPath(forRow: Int(notes.count), inSection: 0)

                // Persist in database
                let realm = RLMRealm.defaultRealm()
                realm.beginWriteTransaction()

                unwindedNote.title = note.title
                unwindedNote.body = note.body
                unwindedNote.id = uuid // This is done for the primary key that Realm needs, unique for each object created.

                realm.addObjects([unwindedNote])
                realm.commitWriteTransaction()

                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

这是因为你的Note数组被初始化为一个空数组,这就是你用来告诉tableView有多少行,即0。

一旦你的Note数组被设置并有一些数据,你就可以调用tableView.reloadData()来重新加载包含数据的数组。

另外,查看上面的代码,您的类继承自UITableViewController,而不是实现UITableViewControllerDelegateUITableViewControllerDataSource。一旦你的类实现了这些,你需要确保将viewController设置为数据源,并在storyboard中或通过代码将tableViewController委托给它。