使用Realm和Swift查询Realm以使用多个节填充numberOfRowsInSection和cellForRowAt [英] Querying Realm to populate numberOfRowsInSection and cellForRowAt with Multiple Sections using Realm and Swift

查看:66
本文介绍了使用Realm和Swift查询Realm以使用多个节填充numberOfRowsInSection和cellForRowAt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Realm和Swift的新手,也是这个网站的新手,所以,如果我的问题措辞不好,请原谅我,但我会尽力而为.来...

I'm new to Realm and Swift, and to this site for that matter, so please forgive me if my question is poorly worded, but I will do my best. Here goes...

基本上,我正在尝试构建Gym应用.这个想法是允许用户键入其锻炼的标题并从Picker View中选择一周中的一天,以分配给该特定锻炼.

Basically I'm trying to build a Gym App. The idea is to allow the user to type out the title of their workout and to select a day of the week from a Picker View, to assign to that particular workout.

话虽如此,我在弄清楚如何编写numberOfRowsInSection函数的编码时遇到了一些麻烦,以便该函数根据特定节中的对象数返回行数.换句话说,根据我在一周中特定日期存储的锻炼次数返回行数.

With that said, I'm having some trouble figuring out how to code the numberOfRowsInSection function so that it returns the number of rows based on the number of objects in that particular section. In other words, to return the number of rows based on the number of workouts that I have stored for that particular day of the week.

cellForRowAt函数也有类似的问题.我正在尝试根据每周的部分/天来找出如何使用锻炼标题填充单元格.

I'm also having a similar problem with the cellForRowAt function. I'm trying to figure out how to populate the cells with titles of the workouts, based on section/day of the week.

任何帮助将不胜感激.

Any help would be greatly 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.

        return 0
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let button = UIButton(type: .system)
        button.setTitleColor(.black, for: .normal)
        button.backgroundColor = .lightGray
        button.setTitle(daysOfWeek[section], for: .normal)

        return button
    }


    func numberOfSections(in tableView: UITableView) -> Int {
        return 7
    }

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

        //Populate with titles of workouts based on section/day of the week.
        //cell.textLabel?.text = days?[indexPath.row].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



        }

        // 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
            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)
        workouts = realm.objects(Workouts.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 Workouts : Object {
            @objc dynamic var name : String = ""
            var parentDay = LinkingObjects(fromType: WeekDays.self, property: "workouts")
        }




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

推荐答案

感谢您向我们提供您的模型.如我所见,您在WeekDay元素上已经有一个Workouts列表,因此填充表视图的查询由此简化了.

Thank you for providing us with your models. As I see you already have a list of Workouts on your WeekDay elements, so your query to populate your Table View is simplified by this.

第一件事.我建议您在控制器中更改对结果的声明,以使用以下

First things first. I recommend you to change your declaration of the results in your controller to use the following

class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate {
    let realm = try! Realm()
    var days : Results<WeekDays>!
    // ... rest of the implementation 
}

这样,您可以使表格视图数据源和委托方法的可选处理无效.

This way you can void the optional handling for the table view datasource and delegate methods.

话虽如此,您只需要在视图控制器上查询WeekDay对象.我通常在viewDidLoad:

That being said, you only need to query the WeekDay objects on the view controller. I usually do this on the viewDidLoad:

days = realm.objects(WeekDays.self)

关联的workouts会自动加载,并与您从数据库中获取的每一天都关联在days阵列上.

The associated workouts are loaded automatically and associated to each of the days you're getting from the database, on the days array.

根据您的要求,您可以为表格视图创建所需数量的节,如下所示:

Based on your requirement you can create the required number of sections for your table view like the following:

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

该代码将创建与days数组大小一样多的部分.下一个任务是在给定的部分中提供行数.这几乎是即时的,因为当天我们已经有一个WorkOuts对象的数组:

That code will create as many section as the size of the days array. The next task is to provide the number of rows in the given section. This is almost immediate because we already have an array of the WorkOuts objects on the day:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let day = days[section]
    return day.workouts.count
}

至此,我们已经提供了表格视图中的部分数(天)和每个部分的行数(与相应日期相关的锻炼).

At this point we already have provided the number of sections in the table view (days) and the number of rows for each section (workouts associated to the corresponding day).

此后,可以基于days数组信息配置每个单元(不要忘记这是一个WeekDays对象的数组,每个对象都包含一个workouts数组.

After this each cell can be configured based on the days array information (don't forget this is an array of WeekDays objects, each one containing an array of workouts.

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

    // Populate with titles of workouts based on section/day of the week.
    cell.textLabel?.text = days[indexPath.section].workouts[indexPath.row].name

    return cell
}

这里的关键是您必须获取WeekDays对象(通过从days数组获取索引为indexPath.section的对象),然后通过获取索引为Workouts对象来获取锻炼的详细信息>从工作日的数组中获取.

The key here is you must obtain the WeekDays object (by getting the object at the index indexPath.section from the days array) and then getting the Workout details by getting the Workouts object at index indexPath.row from the weekday's array.

希望这会有所帮助!

这篇关于使用Realm和Swift查询Realm以使用多个节填充numberOfRowsInSection和cellForRowAt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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