swift - 使用 Realm 和 Swift 查询领域以使用多个部分填充 numberOfRowsInSection 和 cellForRowAt
问题描述
我是 Realm 和 Swift 的新手,也是这个网站的新手,所以如果我的问题措辞不当,请原谅我,但我会尽力而为。开始...
基本上我正在尝试构建一个健身房应用程序。这个想法是允许用户输入他们锻炼的标题并从选取器视图中选择一周中的一天,以分配给该特定锻炼。
话虽如此,我在弄清楚如何对 numberOfRowsInSection 函数进行编码以便它根据该特定部分中的对象数返回行数时遇到了一些麻烦。换句话说,根据我为一周中的特定日期存储的锻炼次数返回行数。
我对 cellForRowAt 函数也有类似的问题。我试图弄清楚如何根据一周中的部分/日期,用锻炼的标题填充单元格。
任何帮助将不胜感激。
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>()
}
解决方案
感谢您向我们提供您的模型。正如我所见,您已经有一个元素列表,因此Workouts
您WeekDay
填充表格视图的查询由此得到简化。
第一件事。我建议您更改控制器中结果的声明以使用以下内容
class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate {
let realm = try! Realm()
var days : Results<WeekDays>!
// ... rest of the implementation
}
这样,您可以取消对表视图数据源和委托方法的可选处理。
话虽如此,您只需要查询WeekDay
视图控制器上的对象。我通常在viewDidLoad
:
days = realm.objects(WeekDays.self)
关联workouts
的会自动加载,并与您从数据库中获取的每一天相关联,在days
阵列上。
根据您的要求,您可以为表格视图创建所需数量的部分,如下所示:
func numberOfSections(in tableView: UITableView) -> Int {
return self.days.count
}
days
该代码将创建与数组大小一样多的部分。下一个任务是提供给定部分中的行数。WorkOuts
这几乎是立竿见影的,因为我们已经有了当天的对象数组:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let day = days[section]
return day.workouts.count
}
此时,我们已经在表格视图中提供了部分的数量(天)和每个部分的行数(与相应日期相关的锻炼)。
在此之后,每个单元格都可以根据days
数组信息进行配置(不要忘记这是一个WeekDays
对象数组,每个对象都包含一个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
对象(通过indexPath.section
从数组的索引处获取对象),然后通过从工作日的数组中获取索引处的对象days
来获取锻炼详细信息。Workouts
indexPath.row
希望这可以帮助!
推荐阅读
- microsoft-graph-api - Graph api /users/{id}/mailFolders/{id}/messages/delta 最多只能列出 5000 封邮件
- java - 结果正确,性能差
- asp.net-core - Docker .Net 6 错误程序不包含适用于入口点的静态“主要”方法
- designer - VB 文件的设计者在重命名和移动解决方案后无法工作
- javascript - 异步 api 调用后在新选项卡中打开窗口
- c++ - 如何正确读取镶木地板文件中的固定长度数组小数?
- php - Wordpress ajax 搜索也在自定义帖子类型中
- java - 根据对象的旋转移动对象
- openedge - 进度警告:在过程中超出 -s 堆栈。这意味着什么?
- robotframework - 获取元素状态以检查没有重复,并且下拉列表中只出现一个值