使用Swift重新排序tableView中的Realm.io数据

时间:2014-07-29 19:55:24

标签: xcode uitableview swift realm

我使用Realm.io实现了ios应用程序的基本示例

我希望能够在我的iOS应用中重新排序表格行并将订单保存回Realm。 为此,Realm模型包含一个名为position的属性。

P.S:很抱歉这么多代码。

import UIKit
import Realm

class Cell: UITableViewCell {
    var position: Int!
    init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: .Subtitle, reuseIdentifier: reuseIdentifier)
    }
}

class Language: RLMObject {
    var title = ""
    var position = Int()
}

class ManagerLanguagesController: UITableViewController, UITableViewDelegate, UITableViewDataSource {

    var array = RLMArray()
    var notificationToken: RLMNotificationToken?
    var editButton = UIBarButtonItem()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        notificationToken = RLMRealm.defaultRealm().addNotificationBlock { note, realm in
            self.reloadData()
        }
        reloadData()
    }

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        return Int(array.count)
    }

    func setupUI() {
        tableView.registerClass(Cell.self, forCellReuseIdentifier: "cell")
        self.title = "Languages"    
        var addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "add")
        editButton = UIBarButtonItem(title: "Edit", style: .Plain, target: self, action: "edit")
        var buttons = [addButton, editButton]
        self.navigationItem.rightBarButtonItems = buttons
    }

    func add() {
        var addLanguageView:UIViewController = self.storyboard.instantiateViewControllerWithIdentifier("newLanguage") as UIViewController
        self.navigationController.presentViewController(addLanguageView, animated: true, completion: nil)
    }

    func edit () {
        if tableView.editing {      
            /* FROM THIS POINT I'M PROBABLY DOING SOMETHING WRONG.. IT IS NOT WORKING  */
            var positionArray = NSMutableArray()
            let realm = RLMRealm.defaultRealm()
            var i = 0

            for var row = 0; row < tableView.numberOfRowsInSection(0); row++ {
                var cellPath = NSIndexPath(forRow: row, inSection: 0)
                var cell:Cell = tableView.cellForRowAtIndexPath(cellPath) as Cell
                positionArray.addObject(cell.position)
            }

            realm.beginWriteTransaction()
            for row: RLMObject in array {
                row["position"] = positionArray[i]
                i++
            }
            realm.commitWriteTransaction()

            /* -- NOT WORKING END -- */

            tableView.setEditing(false, animated: true)
            editButton.style = UIBarButtonItemStyle.Plain
            editButton.title = "Edit"
        } else{
            tableView.setEditing(true, animated: true)
            editButton.title = "Done"
            editButton.style =  UIBarButtonItemStyle.Done
        }
    }

    override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
        let cell = tableView!.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as Cell
        let object = array[UInt(indexPath!.row)] as Language
        cell.textLabel.text = object.title
        cell.position = object.position // I have implemented this to be able to retain initial positions for each row and maybe use this when reordering..
        return cell
    }

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

    override func tableView(tableView: UITableView!, moveRowAtIndexPath sourceIndexPath: NSIndexPath!, toIndexPath destinationIndexPath: NSIndexPath!) {
        //  println("Old index: \(sourceIndexPath.indexAtPosition(sourceIndexPath.length - 1)+1)")
        //  println("New index: \(destinationIndexPath.indexAtPosition(sourceIndexPath.length - 1)+1)")
        // Maybe something needs to be implemented here instead...
    }

    func reloadData() {
        array = Language.allObjects().arraySortedByProperty("position", ascending: true)
        tableView.reloadData()
    }

}

提前致谢

2 个答案:

答案 0 :(得分:5)

您可以将有序数组作为另一个对象的属性,而不是使用位置属性。这样您就不必保持位置是最新的,而是根据需要排列对象:

class Language: RLMObject {
    dynamic var title = ""
}

class LanguageList: RLMObject {
    dynamic var languages = RLMArray(objectClassName: "Language")
}

class ManagerLanguagesController: UITableViewController, UITableViewDelegate, UITableViewDataSource {

    override func viewDidLoad() {
        super.viewDidLoad()

        // create our list
        var realm = RLMRealm.defaultRealm()
        realm.beginWriteTransaction()
        realm.addObject(LanguageList())
        realm.commitWriteTransaction()
        ...
    }

    // helper to get the RLMArray of languages in our list
    func array() -> RLMArray {
        return (LanguageList.allObjects().firstObject() as LanguageList).languages
    }

    override func tableView(tableView: UITableView!, moveRowAtIndexPath sourceIndexPath: NSIndexPath!, toIndexPath destinationIndexPath: NSIndexPath!) {
        var languages = array()
        var object = languages.objectAtIndex(UInt(sourceIndexPath.row)) as Language
        var realm = RLMRealm.defaultRealm()
        realm.beginWriteTransaction()                
        languages.removeObjectAtIndex(UInt(sourceIndexPath.row))
        languages.insertObject(object, atIndex: UInt(destinationIndexPath.row))
        realm.commitWriteTransaction()
    }

    ...
}

答案 1 :(得分:0)

这项工作让我使用realm和swift 2.2在tableview中移动行:

func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
    let aux = TimesHome.mutableCopy() as! NSMutableArray
    let itemToMove = aux[fromIndexPath.row]
    let realm = try! Realm()
    realm.beginWrite()
    aux.removeObjectAtIndex(fromIndexPath.row)
    aux.insertObject(itemToMove, atIndex: toIndexPath.row)
    try! realm.commitWrite()

    TimesHome = aux

    let times = realm.objects(ParciaisTimes)
    if times.count  > 0 {
        for tm in times {
            for i in 1...aux.count {
                if aux[i-1].valueForKey("time_id") as! Int == tm.time_id {
                    realm.beginWrite()
                    tm.ordem = i
                    try! realm.commitWrite()
                }
            }
        }
    }
}