使用 Realm 和 Swift 查询 Realm 以使用多个部分填充 numberOfRowsInSection 和 cellForRowAt
Querying Realm to populate numberOfRowsInSection and cellForRowAt with Multiple Sections using Realm and Swift
我是 Realm 和 Swift 的新手,也是这个网站的新手,所以如果我的问题措辞不当,请原谅我,但我会尽力而为。开始了...
基本上我正在尝试构建一个健身房应用程序。这个想法是允许用户输入他们锻炼的标题,并从选择器视图中输入 select 一周中的某一天,以分配给该特定锻炼。
话虽如此,我在弄清楚如何编写 numberOfRowsInSection 函数的代码时遇到了一些问题,以便它 return 根据该特定部分中的 objects 行数.换句话说,return 行数基于我为一周中的特定一天存储的锻炼次数。
我也遇到了与 cellForRowAt 函数类似的问题。我试图弄清楚如何根据一周的 section/day 用锻炼的标题填充单元格。
如有任何帮助,我们将不胜感激。
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
列表,因此您填充 Table 视图的查询由此得到简化。
要事第一。我建议您更改控制器中的结果声明以使用以下内容
class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate {
let realm = try! Realm()
var days : Results<WeekDays>!
// ... rest of the implementation
}
这样您就可以取消对 table 视图数据源和委托方法的可选处理。
也就是说,您只需要查询视图控制器上的 WeekDay
个对象。我通常在 viewDidLoad
:
上这样做
days = realm.objects(WeekDays.self)
关联的 workouts
会自动加载并关联到您从数据库中获取的每一天,在 days
数组中。
根据您的要求,您可以为 table 视图创建所需数量的部分,如下所示:
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
}
此时我们已经在 table 视图中提供了部分的数量(天)和每个部分的行数(与相应日期相关的锻炼)。
在此之后,可以根据 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
对象(通过从 days
数组获取索引 indexPath.section
处的对象),然后通过获取Workouts
工作日数组中索引 indexPath.row
处的对象。
希望对您有所帮助!
我是 Realm 和 Swift 的新手,也是这个网站的新手,所以如果我的问题措辞不当,请原谅我,但我会尽力而为。开始了...
基本上我正在尝试构建一个健身房应用程序。这个想法是允许用户输入他们锻炼的标题,并从选择器视图中输入 select 一周中的某一天,以分配给该特定锻炼。
话虽如此,我在弄清楚如何编写 numberOfRowsInSection 函数的代码时遇到了一些问题,以便它 return 根据该特定部分中的 objects 行数.换句话说,return 行数基于我为一周中的特定一天存储的锻炼次数。
我也遇到了与 cellForRowAt 函数类似的问题。我试图弄清楚如何根据一周的 section/day 用锻炼的标题填充单元格。
如有任何帮助,我们将不胜感激。
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
列表,因此您填充 Table 视图的查询由此得到简化。
要事第一。我建议您更改控制器中的结果声明以使用以下内容
class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate {
let realm = try! Realm()
var days : Results<WeekDays>!
// ... rest of the implementation
}
这样您就可以取消对 table 视图数据源和委托方法的可选处理。
也就是说,您只需要查询视图控制器上的 WeekDay
个对象。我通常在 viewDidLoad
:
days = realm.objects(WeekDays.self)
关联的 workouts
会自动加载并关联到您从数据库中获取的每一天,在 days
数组中。
根据您的要求,您可以为 table 视图创建所需数量的部分,如下所示:
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
}
此时我们已经在 table 视图中提供了部分的数量(天)和每个部分的行数(与相应日期相关的锻炼)。
在此之后,可以根据 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
对象(通过从 days
数组获取索引 indexPath.section
处的对象),然后通过获取Workouts
工作日数组中索引 indexPath.row
处的对象。
希望对您有所帮助!