使用Realm和Swift查询Realm以使用多个节填充numberOfRowsInSection和cellForRowAt [英] Querying Realm to populate numberOfRowsInSection and cellForRowAt with Multiple Sections using Realm and Swift
问题描述
我是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
的对象),然后通过获取索引为
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屋!