ios - 从 Realm List<> 获取数据

标签 ios swift xcode realm

这就是我的 Realm 类的样子:

class Workout: Object {

    @objc dynamic var date: Date? // Date I did the exercise
    @objc dynamic var exercise: String? // Name of exercise, example; Bench Press, Squat, Deadlift etc..
    // List of sets (to-many relationship)
    var sets = List<Set>()

}

class Set: Object {

    @objc dynamic var reps: Int = 0 // Number of reps for the each set
    @objc dynamic var kg: Double = 0.0 // Amount of weight/kg for each set
    @objc dynamic var notes: String? // Notes for each set

    // Define an inverse relationship to be able to access your parent workout for a particular set (if needed)
    var parentWorkout = LinkingObjects(fromType: Workout.self, property: "sets")

    convenience init(numReps: Int, weight: Double, aNote: String) {
       self.init()
       self.reps = numReps
       self.kg = weight
       self.notes = aNote
    }
}

我想获取上次进行此练习时每组的重量(公斤)和重复次数。所以我正在尝试这样的事情。要使用exercise“TextExercise2”查询锻炼,我这样做:

func queryFromRealm() {
    let realm = try! Realm()

    let getExercises = realm.objects(Workout.self).filter("exercise = 'Text Exercise2'").sorted(byKeyPath: "date",ascending: false)

    print(getExercises.last!)

    myTableView.reloadData()
}

这给了我这样的输出:

Workout {
    date = 2019-11-24 00:33:21 +0000;
    exercise = Text Exercise2;
    sets = List<Set> <0x600003fcdb90> (
        [0] Set {
            reps = 12;
            kg = 7;
            notes = light workout;
        },
        [1] Set {
            reps = 12;
            kg = 8;
            notes = medium workout;
        },
        [2] Set {
            reps = 12;
            kg = 9;
            notes = heavy workout;
        }
    );
}

这就是我将数据从 mainVC 传递到ExerciseCreatorViewController 的方式:

var selectedWorkout = Workout()
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "toEditExerciseCreatorSegue" {
            if let nextVC = segue.destination as? ExerciseCreatorViewController {
                nextVC.selectedWorkout = self.selectedWorkout
            }
        }
    }

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

        selectedWorkout = resultFromDate[indexPath.row]

        performSegue(withIdentifier: "toEditExerciseCreatorSegue", sender: self)
    }

从现在开始,我想将这些添加到 UITableView 中,其中每行包含公斤和重复次数。我怎样才能做到这一点?我应该以某种方式改变我的设置吗?期待您的帮助。

编辑 - 上传整个ExerciseCreatorViewController.swift文件:

import UIKit
import RealmSwift

class ExerciseCreatorViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {

    let menuButtonSize: CGSize = CGSize(width: 44, height: 44)
    let actionButtonSize: CGSize = CGSize(width: 44, height: 66)
    let screenSize: CGRect = UIScreen.main.bounds

    var resultFromDate:[Workout] = []
    var selectedWorkout = Workout()


    @IBOutlet var exerciseNameTextField: UITextField!
    let exerciseName = UILabel()

    @IBOutlet var navView: UIView!
    let navLabel = UILabel()

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self
        exerciseNameTextField.delegate = self

        // Get main screen bounds
        let screenSize: CGRect = UIScreen.main.bounds
        let screenWidth = screenSize.width
        let screenHeight = screenSize.height

        //self.view.backgroundColor = UIColor(red: 32/255, green: 32/255, blue: 32/255, alpha: 1.0)
        self.view.backgroundColor = UIColor.white

        // Navigation View
        navView.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: 66)
        navView.frame.origin.y = 28
        //navLabel.backgroundColor = UIColor(red: 32/255, green: 32/255, blue: 32/255, alpha: 1.0)
        navLabel.backgroundColor = UIColor.white
        //navView.backgroundColor = UIColor.red.withAlphaComponent(0.5)
        self.view.addSubview(navView)

        // Navigation Label
        self.navView.addSubview(navLabel)
        navLabel.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: 66)
        navLabel.textAlignment = .center
        navLabel.font = UIFont.boldSystemFont(ofSize: 20)
        navLabel.textColor = UIColor.black
        //navLabel.text = "Workout"
        navLabel.text = "Log workout"
        navLabel.adjustsFontSizeToFitWidth = true
        navLabel.isUserInteractionEnabled = true
        self.view.backgroundColor = UIColor.white

        configureButtons()

        setupFooter()

        self.hideKeyboard()

        print("Printing ... ... ...")
        print(selectedWorkout)
    }

    func setupFooter() {
        let customView = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: 50))
        customView.backgroundColor = UIColor.lightGray
        let button = UIButton(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: 50))
        button.setTitle("Add Set", for: .normal)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        customView.addSubview(button)

        tableView.tableFooterView = customView
    }

    @objc func buttonAction(_ sender: UIButton!) { // Add new set/row in tableView
        print("Button tapped")

        let a = Array(stride(from: 1, through: 50, by: 1)) // Haven't tested yet. Add new set in array

        setsArray.append("a")

        // Update Table Data
        tableView.beginUpdates()
        tableView.insertRows(at: [
            (NSIndexPath(row: setsArray.count-1, section: 0) as IndexPath)
        ], with: .automatic)
        tableView.endUpdates()
    }

     func configureButtons() {
           confiureCloseButton()
           confiureSaveButton()
           confiureClearButton()
       }

       func confiureCloseButton() {
           //let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
           let button = UIButton(frame: CGRect(origin: CGPoint.zero, size: menuButtonSize))
           button.setImage(UIImage(named: "icon_close"), for: UIControl.State.normal)
           button.setImage(UIImage(named: "icon_close")?.alpha(0.5), for: UIControl.State.highlighted)
           button.center = CGPoint(x: 50, y: 61)
           button.layer.cornerRadius = button.frame.size.width/2
           button.layer.zPosition = 1
           button.addTarget(self, action: #selector(closeButtonAction), for: .touchUpInside)
           button.setTitleColor(.black, for: UIControl.State.normal)
           button.backgroundColor = UIColor.red
        button.isUserInteractionEnabled = true
           self.view.addSubview(button)
       }

       @objc func closeButtonAction(sender: UIButton!) {
           self.dismiss(animated: true, completion: nil)
       }



       func confiureSaveButton() {
           let button = UIButton(frame: CGRect(origin: CGPoint(x: screenSize.width-44-8, y: 28), size: actionButtonSize))
           button.setTitle("Save", for: UIControl.State.normal)
           //button.backgroundColor = UIColor.blue
           button.layer.zPosition = 1
           button.addTarget(self, action: #selector(saveButtonAction), for: .touchUpInside)
           button.setTitleColor(.black, for: UIControl.State.normal)
        button.isUserInteractionEnabled = true
           self.view.addSubview(button)
       }

       @objc func saveButtonAction(sender: UIButton!) {
           saveWorkout()
       }

       func confiureClearButton() {
           let button = UIButton(frame: CGRect(origin: CGPoint(x: screenSize.width-44-8-44-8, y: 28), size: actionButtonSize))
           button.setTitle("Clear", for: UIControl.State.normal)
           //button.backgroundColor = UIColor.red
           button.layer.zPosition = 1
           button.addTarget(self, action: #selector(clearButtonAction), for: .touchUpInside)
        button.isUserInteractionEnabled = true
           button.setTitleColor(.black, for: UIControl.State.normal)

           self.view.addSubview(button)
       }

       @objc func clearButtonAction(sender: UIButton!) {
           clearWorkout()
       }

    func clearWorkout() { // Clear workout exercise
        print("clear")
    }
    let nowDate = Date()




    var setsArray = [String]()
    var previousArray = [String]()
    var kgArray = [String]()
    var repsArray = [String]()
    var notesArray = [String]()

    func saveWorkout() { // Save workout exercise
        if setsArray.isEmpty {//if !setsArray.isEmpty {
            print("Saving workout...")
            /*let realm = try! Realm()


            let myWorkout = Workout()
            myWorkout.date = nowDate
            myWorkout.exercise = "Text Exercise"

            let aSet0 = Set(numReps: 12, weight: 11.5, aNote: "light workout")
            let aSet1 = Set(numReps: 12, weight: 12.5, aNote: "medium workout")
            let aSet2 = Set(numReps: 12, weight: 21.0, aNote: "heavy workout")

            myWorkout.sets.append(objectsIn: [aSet0, aSet1, aSet2] )

            try! realm.write {
                realm.add(myWorkout)
                print("Saved!")
            }*/
        } else {

            // create the alert
            let alert = UIAlertController(title: nil, message: "Please add any exercise before saving!", preferredStyle: UIAlertController.Style.alert)

            // add an action (button)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))

            // show the alert
            self.present(alert, animated: true, completion: nil)
        }
    }

    // number of rows in table view
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return setsArray.count
    }

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

        let realm = try! Realm()
        let getExercises = realm.objects(Workout.self).filter("exercise = 'Text Exercise2'").sorted(byKeyPath: "date",ascending: false)

        print(getExercises.last!)

        let myWorkout = Workout()

        // Find the Workout instance "Bench Press"
        let benchPressWorkout = realm.objects(Workout.self).filter("exercise = 'Text Exercise2'").sorted(byKeyPath: "date",ascending: false)
        // Access the sets for that instance
        let sets = benchPressWorkout[0].sets

        for i in sets.indices {
            let set0 = sets[i]

            // Access reps and kg for set 0
            let reps0 = set0.reps
            let kg0 = set0.kg
            // and so on ...

            print([kg0]) // number of KG
            print([reps0]) // number of reps

            cell.previousTextField.text = "\(kg0) x \(reps0)"

        }

        cell.setLabel.text = "\(indexPath.row + 1)"

        return cell
    }

    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("tapped")
    }
}

编辑:我有三个对象,如 @rs7 之前建议的:

锻炼.swift:

@objc dynamic var id = 0
@objc dynamic var date: Date?
// List of exercises (to-many relationship)
var exercises = List<Exercise>()

override static func primaryKey() -> String? {
    return "id"
}

练习.swift

class Exercise: Object {

    @objc dynamic var name: String?
    // List of sets (to-many relationship)
    var sets = List<Set>()
    var parentWorkout = LinkingObjects(fromType: Workout.self, property: "exercises")
}

设置.swift

class Set: Object {

    @objc dynamic var reps: Int = 0
    @objc dynamic var kg: Double = 0.0
    @objc dynamic var notes: String?
    // Define an inverse relationship to be able to access your parent workout for a particular set (if needed)
    var parentExercise = LinkingObjects(fromType: Exercise.self, property: "sets")

    convenience init(numReps: Int, weight: Double, aNote: String) {
       self.init()
       self.reps = numReps
       self.kg = weight
       self.notes = aNote
    }
}

最佳答案

无论如何我都会给你答案,但不要忘记修复你的代码。

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // number of rows = number of sets (not counting the header row)
    return selectedExercise.sets.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ExerciseCreatorCell
    let currentSet = selectedExercise.sets[indexPath.row]
    cell.setNumberLabel.text = "\(indexPath.row)"
    cell.kgLabel.text = "\(currentSet.kg)"
    cell.repsLabel.text = "\(currentSet.reps)"
    return cell
}

关于ios - 从 Realm List<> 获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59013865/

相关文章:

ios - 什么 MPMediaItem 元数据组合可以被视为 GUID?

ios - 关闭 UIViewController 时停止视频流

ios - MTLocation 操作方法

xcode "compile source as"覆盖特定文件

ios - 永久更改.mlmodel自动生成的文件

ios - 如何在 iOS 中设置提醒消息的可访问性标签?

Swift image Aspect Fill 高图像不起作用

ios - 创建一个包含 n 个空格或其他重复字符的字符串

ios - Swift - UIButton 按下时未突出显示

ios - Xcode 中的流控制