Swift实现TableView分类去重显示及点击分类展示对应语录
没问题,我来帮你搞定这个需求!咱们一步步来,从数据整理到TableView实现都给你安排明白~
第一步:整理按分类分组的数据
首先得把QuoteBrain里的原始语录数组,转换成按分类分组的结构,这样后续TableView可以直接用。我给你改造下QuoteBrain,增加两个计算属性:一个是按分类分组的字典,另一个是去重后的分类列表:
struct Quote { var category: String var text: String } struct QuoteBrain { let quotes = [ Quote(category: "Friends", text: "blablabla"), Quote(category: "Friends", text: "Blobloblo"), Quote(category: "Love", text: "Love U Sooooooo") // 其他语录继续加在这里... ] // 把语录按分类分组,key是分类名,value是对应分类的所有Quote var groupedQuotes: [String: [Quote]] { Dictionary(grouping: quotes, by: { $0.category }) } // 获取去重后的分类列表,可选排序让显示更整齐 var categories: [String] { Array(groupedQuotes.keys).sorted() } }
第二步:实现分类列表的TableView
接下来做第一个TableView,用来显示去重后的分类(比如你的案例里就是Friends和Love两个选项)。
假设你有一个CategoryViewController,里面放了TableView,代码可以这么写:
import UIKit class CategoryViewController: UIViewController, UITableViewDataSource { let quoteBrain = QuoteBrain() @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self // 注册默认的cell,你也可以用自定义cell tableView.register(UITableViewCell.self, forCellReuseIdentifier: "CategoryCell") } // 返回分类的数量 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { quoteBrain.categories.count } // 设置每个cell的内容 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath) let category = quoteBrain.categories[indexPath.row] cell.textLabel?.text = category // 加个箭头提示用户可以点击 cell.accessoryType = .disclosureIndicator return cell } }
第三步:点击分类跳转显示对应语录
现在需要做第二个页面,用来展示选中分类下的所有语录,然后处理第一个TableView的点击事件。
先写语录列表的ViewController
创建一个QuoteListViewController,接收传递过来的语录数组:
import UIKit class QuoteListViewController: UIViewController, UITableViewDataSource { // 用来接收从分类页面传过来的语录数组 var quotes: [Quote] = [] @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.register(UITableViewCell.self, forCellReuseIdentifier: "QuoteCell") // 把导航栏标题设置为当前分类名(可选) if let firstQuote = quotes.first { title = firstQuote.category } } // 返回当前分类下的语录数量 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { quotes.count } // 设置每个语录cell的内容 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "QuoteCell", for: indexPath) let quote = quotes[indexPath.row] cell.textLabel?.text = quote.text return cell } }
处理分类列表的点击事件
回到CategoryViewController,实现UITableViewDelegate的点击方法,跳转到语录列表页面:
extension CategoryViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 点击后取消选中状态 tableView.deselectRow(at: indexPath, animated: true) // 获取选中的分类 let category = quoteBrain.categories[indexPath.row] // 获取该分类下的所有语录 guard let quotesInCategory = quoteBrain.groupedQuotes[category] else { return } // 跳转到语录列表页面(这里假设用Storyboard跳转,记得给QuoteListViewController设置storyboard ID) if let quoteVC = storyboard?.instantiateViewController(withIdentifier: "QuoteListViewController") as? QuoteListViewController { quoteVC.quotes = quotesInCategory navigationController?.pushViewController(quoteVC, animated: true) } } }
这样一套下来,你的需求就实现啦:第一个TableView只显示每个分类一次,点击分类就能跳转到对应页面查看所有语录~
内容的提问来源于stack exchange,提问作者Marianne Dubois Massé
相关产品推荐
相关产品推荐

