错误:尝试从第1节删除第0行,但更新前只有1个节(Swift和Realm) [英] ERROR: attempt to delete row 0 from section 1, but there are only 1 sections before the update (Swift and Realm)

查看:76
本文介绍了错误:尝试从第1节删除第0行,但更新前只有1个节(Swift和Realm)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我对Realm和Swift还是相当陌生,我正在构建我的第一个Gym App,并且目前正在为这个错误而努力.每当我尝试滑动以删除行/节时,都会出现此错误.

So I'm fairly new to Realm and Swift and I'm currently building my first Gym App and I'm currently struggling with this error. I get this error each time I attempt to swipe to delete a row/section.

我认为我正在正确地更新我的Realm,但显然不是因为我一直遇到相同的错误.

I think that I'm updating my Realm correctly, but apparently not because I keep getting the same error.

任何帮助或指导将不胜感激.

Any help or guidance would be much appreciated.

import UIKit
import RealmSwift
import SwipeCellKit


class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate {


    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.row]) != 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

            if let workoutForDeletion = self.days?[indexPath.row] {
                do {
                    try self.realm.write {
                        self.realm.delete(workoutForDeletion)
                    }
                } catch {
                    print("Error deleting workout, \(error)")
                }
            }
            self.WorkoutsTableView.reloadData()
        }
        // 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()

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

推荐答案

我认为您对self.days的取消引用感到困惑.它看起来像,这是一连串的日子,每一天都包含一系列的锻炼. cellForRowAt函数操作支持此功能,以计算每一行中的内容:

I think you're confusing the dereferencing of self.days. It looks like this is an array of days, each containing an array of workouts. This is supported by the cellForRowAt function operation for working out what is in each row:

cell.textLabel?.text = days[indexPath.section].workouts[indexPath.row].name

但是对于您的删除代码,您仅通过行号取消引用days,即:

But for your deletion code you are dereferencing days only by the row number, i.e.:

 if let workoutForDeletion = self.days?[indexPath.row] {

那里没有使用indexPath.section.更正这一点将有所帮助.

There is no use of indexPath.section there. Correcting that will help.

不过,您可能希望查看用于删除行的常用代码,该代码将使用类似于以下内容的代码:-

You may want to look into the usual code for deleting rows though, which is to use code similar to below:-

days[indexPath.section].remove(at: indexPath.row) // Make this a realm update though
tableView.deleteRows(at: [indexPath], with: .fade)

保存完整的数据重装并为您提供更好的UI更新.

Which saves the complete reload of data and gives you a nicer UI update.

这篇关于错误:尝试从第1节删除第0行,但更新前只有1个节(Swift和Realm)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆