使用 Realm 和 Swift,具有多个按字母顺序排列的部分的 UITableView,具有与相同数据连接的多个标签
UITableView with Multiple Sections in Alphabetical Order using Realm and Swift, with multiple labels connected with same data
现在已经尝试解决这个问题 10 多天了,但仍然没有运气解决这个问题。
我正在尝试根据 "ExerciseName" 列的名称从 A-Z 的字母顺序向 table 视图添加部分。我还有一个"BodyPartName"、"CategoryName"?每个 "ExerciseName" 的数据列。
我想从 A-Z 填充部分,并将 ExerciseName 分类到每个部分,同一行中其他标签的 BodyPartName 和 CategoryName。
我成功实现了 A-Z 部分下的 ExerciseName,但无法将 BodyPartName 和 CategoryName 添加到同一行的其他标签中。请帮忙!!
预期结果
一个
Abs“(核心)”
手臂推举“(手臂)”“(哑铃)”
B
二头肌弯举“(手臂)”“(杠铃)”
向后扩展“(向后)”“(机器)”
无法为同一行填充 "BodyPartName" 标签和 "CategoryName" 标签。
这是我的领域数据模型:
class Exercises: Object
{
@objc dynamic var ExerciseID = 0
@objc dynamic var ExerciseName = ""
@objc dynamic var BodyPartName = ""
@objc dynamic var CategoryName: String? = ""
//Adding Parent Table BodyPart & Category.
var parentBodyParts = LinkingObjects(fromType: BodyParts.self, property: "exercises")
var parentCategory = LinkingObjects(fromType: Category.self, property: "category")
}
我的代码:
let realm = try! Realm()
var exerciseArray: Results<Exercises>!
override func viewDidLoad()
{
super.viewDidLoad()
tableView.register(UINib(nibName: "customCell", bundle: nil), forCellReuseIdentifier: cellID)
sectionFunction()
}
var sectionDictionary = [String:[String]]()
var sectionTitles = [String]()
func sectionFunction()
{
exerciseArray = realm.objects(Exercises.self).sorted(byKeyPath: "ExerciseName")
for section in exerciseArray
{
let sectionKey = String(section.ExerciseName.prefix(1))
if var sectionValues = sectionDictionary[sectionKey]
{
sectionValues.append(section.ExerciseName) // Adding ExerciseNames to the Keys
sectionDictionary[sectionKey] = sectionValues
}
else
{
sectionDictionary[sectionKey] = [section.ExerciseName]
}
}
sectionTitles = [String](sectionDictionary.keys)
sectionTitles = sectionTitles.sorted(by: {[=12=] < }) // Alphabetical order for Keys:Values
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return sectionTitles.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
return sectionTitles[section]
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]?
{
return sectionTitles
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let sectionKey = sectionTitles[section]
if let sectionValues = sectionDictionary[sectionKey]
{
return sectionValues.count
}
return 0
// return exercises.filter("ExerciseName == %@", sectionNames[section]).count
}
// Register custom cell for Table View
let cellID = "customCell"
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! customCell
let sectionKey = sectionTitles[indexPath.section]
if let sectionValues = sectionDictionary[sectionKey]
{
exerciseArray = realm.objects(Exercises.self).sorted(byKeyPath: "ExerciseName")
cell.exerciseName.text = sectionValues[indexPath.row]
cell.bodyPartName.text = exerciseArray.filter("ExerciseName == %@", sectionValues[indexPath.row]) [indexPath.row].BodyPartName
cell.categoryName.text = exerciseArray.filter("ExerciseName == %@", sectionValues[indexPath.row]) [indexPath.row].CategoryName ?? ""
cell.backgroundColor = .clear
}
return cell
}
自定义单元格:
class customCell: UITableViewCell {
@IBOutlet weak var exerciseName: UILabel!
@IBOutlet weak var bodyPartName: UILabel!
@IBOutlet weak var categoryName: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
问题中的代码存在很多问题,我不想细细剖析它们,而是提供一个可能有帮助的示例。
假设我们有一堆水果存储在 Realm 中。我们想使用 sections
在 tableview 中按字母顺序显示这些内容
A
Apple
B
Banana
等等
第一段代码是一个结构,用于保存部分标题,然后是该部分中的水果数组。此外,一个 class fruitNameArray 将充当我们的 tableView 数据源,其中包含所有 FruitStructs。
struct FruitStruct {
var sectionTitle = ""
var fruitNameArray = [String]()
}
var fruitDataSource = [FruitStruct]()
我正在使用数组来保存初始数据,但在您的情况下,它可能是从领域填充的领域结果 object。这是从 viewDidLoad 调用的,用于将我们的数据组织到 dataSource 数组中
func setupDataSourceData() {
let fruitArray = ["Apple", "Pear", "Banana", "Bing Cherry", "Grape", "Orange", "Plum", "Watermelon", "Cantelope"]
let allFirstChars = fruitArray.map { String([=12=].prefix(1)) } //get all first chars for section titles
let sectionTitles = Array(Set(allFirstChars)).sorted() //eliminate dups and sort
//iterate over the unique section titles and get the fruits that are in that section
// sort and then craft structs to hold the title and the associated fruits
sectionTitles.forEach { firstChar in
let results = fruitArray.filter { [=12=].prefix(1) == firstChar }
let sortedFruits = results.sorted()
let fruit = FruitStruct(sectionTitle: firstChar, fruitNameArray: sortedFruits)
fruitDataSource.append(fruit)
}
for fruitData in fruitDataSource {
print(fruitData.sectionTitle)
let fruits = fruitData.fruitNameArray
for fruitName in fruits {
print(" \(fruitName)")
}
}
}
然后,tableView 需要 4 个函数来显示部分,然后显示每个部分中的行。您似乎有这 4 个,但还有一个 sectionIndexTitles
可能不需要。
//
//handle sections
//
func numberOfSections(in tableView: UITableView) -> Int {
return self.fruitDataSource.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let title = self.fruitDataSource[section].sectionTitle
return title
}
//
//handleTableView rows
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let rowsInSection = self.fruitDataSource[section].fruitNameArray.count
return rowsInSection
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let text = self.fruitDataSource[indexPath.section].fruitNameArray[indexPath.row]
cell.textLabel?.text = text
return cell
}
请注意,在填充 tableView 时,我没有执行任何过滤和任何其他操作。该部分代码需要快速并尽可能地响应 UI。
我刚得到一个字符串
let text = self.fruitDataSource[indexPath.section].fruitNameArray[indexPath.row]
但在您的情况下,您可能想要 return 锻炼 object 然后您可以在其中获取 exerciseName 和 bodypartName,然后在自定义 cellView
中分配它们
最佳实践注意事项:class 属性应小写 - exerciseName,而不是大写,ExerciseName。 Class 和结构名称通常大写。
现在已经尝试解决这个问题 10 多天了,但仍然没有运气解决这个问题。
我正在尝试根据 "ExerciseName" 列的名称从 A-Z 的字母顺序向 table 视图添加部分。我还有一个"BodyPartName"、"CategoryName"?每个 "ExerciseName" 的数据列。
我想从 A-Z 填充部分,并将 ExerciseName 分类到每个部分,同一行中其他标签的 BodyPartName 和 CategoryName。
我成功实现了 A-Z 部分下的 ExerciseName,但无法将 BodyPartName 和 CategoryName 添加到同一行的其他标签中。请帮忙!!
预期结果
一个
Abs“(核心)”
手臂推举“(手臂)”“(哑铃)”
B
二头肌弯举“(手臂)”“(杠铃)”
向后扩展“(向后)”“(机器)”
无法为同一行填充 "BodyPartName" 标签和 "CategoryName" 标签。
这是我的领域数据模型:
class Exercises: Object
{
@objc dynamic var ExerciseID = 0
@objc dynamic var ExerciseName = ""
@objc dynamic var BodyPartName = ""
@objc dynamic var CategoryName: String? = ""
//Adding Parent Table BodyPart & Category.
var parentBodyParts = LinkingObjects(fromType: BodyParts.self, property: "exercises")
var parentCategory = LinkingObjects(fromType: Category.self, property: "category")
}
我的代码:
let realm = try! Realm()
var exerciseArray: Results<Exercises>!
override func viewDidLoad()
{
super.viewDidLoad()
tableView.register(UINib(nibName: "customCell", bundle: nil), forCellReuseIdentifier: cellID)
sectionFunction()
}
var sectionDictionary = [String:[String]]()
var sectionTitles = [String]()
func sectionFunction()
{
exerciseArray = realm.objects(Exercises.self).sorted(byKeyPath: "ExerciseName")
for section in exerciseArray
{
let sectionKey = String(section.ExerciseName.prefix(1))
if var sectionValues = sectionDictionary[sectionKey]
{
sectionValues.append(section.ExerciseName) // Adding ExerciseNames to the Keys
sectionDictionary[sectionKey] = sectionValues
}
else
{
sectionDictionary[sectionKey] = [section.ExerciseName]
}
}
sectionTitles = [String](sectionDictionary.keys)
sectionTitles = sectionTitles.sorted(by: {[=12=] < }) // Alphabetical order for Keys:Values
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return sectionTitles.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
return sectionTitles[section]
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]?
{
return sectionTitles
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let sectionKey = sectionTitles[section]
if let sectionValues = sectionDictionary[sectionKey]
{
return sectionValues.count
}
return 0
// return exercises.filter("ExerciseName == %@", sectionNames[section]).count
}
// Register custom cell for Table View
let cellID = "customCell"
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! customCell
let sectionKey = sectionTitles[indexPath.section]
if let sectionValues = sectionDictionary[sectionKey]
{
exerciseArray = realm.objects(Exercises.self).sorted(byKeyPath: "ExerciseName")
cell.exerciseName.text = sectionValues[indexPath.row]
cell.bodyPartName.text = exerciseArray.filter("ExerciseName == %@", sectionValues[indexPath.row]) [indexPath.row].BodyPartName
cell.categoryName.text = exerciseArray.filter("ExerciseName == %@", sectionValues[indexPath.row]) [indexPath.row].CategoryName ?? ""
cell.backgroundColor = .clear
}
return cell
}
自定义单元格:
class customCell: UITableViewCell {
@IBOutlet weak var exerciseName: UILabel!
@IBOutlet weak var bodyPartName: UILabel!
@IBOutlet weak var categoryName: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
问题中的代码存在很多问题,我不想细细剖析它们,而是提供一个可能有帮助的示例。
假设我们有一堆水果存储在 Realm 中。我们想使用 sections
在 tableview 中按字母顺序显示这些内容A
Apple
B
Banana
等等
第一段代码是一个结构,用于保存部分标题,然后是该部分中的水果数组。此外,一个 class fruitNameArray 将充当我们的 tableView 数据源,其中包含所有 FruitStructs。
struct FruitStruct {
var sectionTitle = ""
var fruitNameArray = [String]()
}
var fruitDataSource = [FruitStruct]()
我正在使用数组来保存初始数据,但在您的情况下,它可能是从领域填充的领域结果 object。这是从 viewDidLoad 调用的,用于将我们的数据组织到 dataSource 数组中
func setupDataSourceData() {
let fruitArray = ["Apple", "Pear", "Banana", "Bing Cherry", "Grape", "Orange", "Plum", "Watermelon", "Cantelope"]
let allFirstChars = fruitArray.map { String([=12=].prefix(1)) } //get all first chars for section titles
let sectionTitles = Array(Set(allFirstChars)).sorted() //eliminate dups and sort
//iterate over the unique section titles and get the fruits that are in that section
// sort and then craft structs to hold the title and the associated fruits
sectionTitles.forEach { firstChar in
let results = fruitArray.filter { [=12=].prefix(1) == firstChar }
let sortedFruits = results.sorted()
let fruit = FruitStruct(sectionTitle: firstChar, fruitNameArray: sortedFruits)
fruitDataSource.append(fruit)
}
for fruitData in fruitDataSource {
print(fruitData.sectionTitle)
let fruits = fruitData.fruitNameArray
for fruitName in fruits {
print(" \(fruitName)")
}
}
}
然后,tableView 需要 4 个函数来显示部分,然后显示每个部分中的行。您似乎有这 4 个,但还有一个 sectionIndexTitles
可能不需要。
//
//handle sections
//
func numberOfSections(in tableView: UITableView) -> Int {
return self.fruitDataSource.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let title = self.fruitDataSource[section].sectionTitle
return title
}
//
//handleTableView rows
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let rowsInSection = self.fruitDataSource[section].fruitNameArray.count
return rowsInSection
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
let text = self.fruitDataSource[indexPath.section].fruitNameArray[indexPath.row]
cell.textLabel?.text = text
return cell
}
请注意,在填充 tableView 时,我没有执行任何过滤和任何其他操作。该部分代码需要快速并尽可能地响应 UI。
我刚得到一个字符串
let text = self.fruitDataSource[indexPath.section].fruitNameArray[indexPath.row]
但在您的情况下,您可能想要 return 锻炼 object 然后您可以在其中获取 exerciseName 和 bodypartName,然后在自定义 cellView
中分配它们最佳实践注意事项:class 属性应小写 - exerciseName,而不是大写,ExerciseName。 Class 和结构名称通常大写。