簡體   English   中英

如何使用 Realm 和 Swift 從 TableView 中刪除一個部分和一行?

[英]How to delete a section and a row from a TableView with Realm and Swift?

能夠查看。 我目前正在開發這個健身房應用程序,希望能在這里得到一些指導。

基本上我想要的是能夠滑動單元格並刪除與該行相關聯的行和部分。

當我運行我的代碼時,這是我得到的錯誤

'試圖從第 1 節中刪除第 0 行,但更新前只有 1 個節'

任何幫助將非常感激。

class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate, CollapsibleTableSectionDelegate {


    let realm = try! Realm()

    var workouts : Results<Workouts>?
    var days : Results<WeekDays>!

    var daysOfWeek : [String] = ["Monday", "Tuesday", "Wednsday", "Thursday", "Friday", "Saturday", "Sunday"]

    let picker = UIPickerView()


    @IBOutlet weak var WorkoutsTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        WorkoutsTableView.delegate = self
        WorkoutsTableView.dataSource = self


        picker.delegate = self
        picker.dataSource = self

        loadCategories()

    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        tableView.rowHeight = 80.0

        //Populate based on the # of workouts in each day.

        let day = days[section]
        return day.workouts.count
    }


    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return days[section].day
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return days.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SwipeTableViewCell

        cell.delegate = self

        if (days?[indexPath.section]) != nil {
            cell.accessoryType = .disclosureIndicator
            //Populate with titles of workouts based on section/day of the week.
            //cell.textLabel?.text = days?[indexPath.row].workouts[indexPath.row].name
            cell.textLabel?.text = days[indexPath.section].workouts[indexPath.row].name
        }
        return cell
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {

        guard orientation == .right else { return nil }

        let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in

            self.updateModel(at: indexPath)

        }
        // customize the action appearance
        deleteAction.image = UIImage(named: "delete-icon")

        return [deleteAction]
    }

    func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
        var options = SwipeOptions()
        options.expansionStyle = .destructive
        return options
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
    }



    @IBAction func AddWorkoutButton(_ sender: UIButton) {
        var textField = UITextField()
        textField.becomeFirstResponder()
        let alert = UIAlertController(title: "New Workout", message: "Please name your workout...", preferredStyle: .alert)

        let addAction = UIAlertAction(title: "Add Workout", style: .default) { (UIAlertAction) in
                //Add workout to database
                //Create a two dimensional array object in Realm with numbers corresponding to each day of the week.
                //Append workouts to the day in the dictionary that the user selects.
            let newWorkout = Workouts()
            let dow = WeekDays()
            dow.day = self.daysOfWeek[self.picker.selectedRow(inComponent: 0)]
            newWorkout.name = textField.text!
            dow.workouts.append(newWorkout)

            self.save(newDay: dow)
        }

        alert.addTextField { (alertTextField) in
            alertTextField.placeholder = "Muscle Group"
            textField = alertTextField
            alertTextField.inputView = self.picker
        }

        alert.addAction(addAction)

        present(alert, animated: true, completion: nil)
    }

    func save(newDay: WeekDays){
        do {
            try realm.write {
                realm.add(newDay)
            }
        } catch {
            print("Error saving workout \(error)")
        }
        WorkoutsTableView.reloadData()
    }

    func updateModel(at indexPath: IndexPath){
        if let workoutForDeletion = self.days?[indexPath.section]{
            do {
                try self.realm.write {
                    self.realm.delete(workoutForDeletion)
                }
            } catch {
                print("Error deleting workout, \(error)")
            }
        }
        self.WorkoutsTableView.reloadData()
    }

    func loadCategories(){
        days = realm.objects(WeekDays.self)
        WorkoutsTableView.reloadData()
    }

    @IBAction func EditWorkout(_ sender: UIBarButtonItem) {

    }

}

extension WorkoutsViewController : UIPickerViewDelegate, UIPickerViewDataSource {

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 7
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return daysOfWeek[row]
    }
}



class WeekDays : Object {
    @objc dynamic var day : String = ""
    let workouts = List<Workouts>()
}

class Workouts : Object {
    @objc dynamic var name : String = ""
    var parentDay = LinkingObjects(fromType: WeekDays.self, property: "workouts")
}

如果您嘗試刪除整個部分,那么您的代碼是正確的。 嘗試調用 loadCategories 而不是重新加載 tableView 以查看是否有幫助。 請參閱下面的更新代碼:

將該行改為:

func updateModel(at indexPath: IndexPath){
        if let workoutForDeletion = self.days?[indexPath.section] {
            do {
                try self.realm.write {
                    self.realm.delete(workoutForDeletion)
                }
            } catch {
                print("Error deleting workout, \(error)")
            }
        }
        self.loadCategories()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM