错误:尝试从第1节中删除第0行,但更新前只有1个节(Swift和Realm)

时间:2019-12-01 17:26:55

标签: swift realm tableview

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

我认为我正在正确更新Realm,但显然不是因为我不断收到相同的错误。

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

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

1 个答案:

答案 0 :(得分:1)

我认为您对import os from flask import * from flask_session import Session from sqlalchemy import * from sqlalchemy.orm import scoped_session, sessionmaker from models import * app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL") # Check for environment variable if not os.getenv("DATABASE_URL"): raise RuntimeError("DATABASE_URL is not set") app.secret_key = '######' app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db.init_app(app) engine = create_engine(os.getenv("DATABASE_URL")) db = scoped_session(sessionmaker(bind=engine)) ... @app.route("/submitpatient", methods=["POST"]) def submitpatient(): fname = request.form.get("fname") mname = request.form.get("mname") lname = request.form.get("lname") patient = Patient(fname=fname, mname=mname, lname=lname) db.session.add(patient) db.session.commit() return redirect(url_for('index')) 的取消引用感到困惑。它看起来像,这是一连串的日子,每一天都包含一系列的锻炼。 self.days函数操作支持此功能,用于计算每一行中的内容:

cellForRowAt

但是对于您的删除代码,您仅通过行号来引用cell.textLabel?.text = days[indexPath.section].workouts[indexPath.row].name ,即:

days

那里没有使用 if let workoutForDeletion = self.days?[indexPath.row] { 。纠正将有所帮助。

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

indexPath.section

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