Swift:如何在TableViewController中按日期排序两种自定义单元格
搞定按日期混合排序网页数据与推文的方案
没问题,我来帮你解决这个把网页数据和推文按日期混排的需求!核心思路是把两种不同类型的数据统一成一个带日期的通用集合,排序后再渲染对应的单元格,具体步骤如下:
1. 定义通用数据模型
我们需要一个能同时容纳网页数据和推文的枚举,并且提供统一的日期访问入口,这样后续排序就方便了:
enum UnifiedFeedItem { case article(LocationModel) case tweet(TWTRTweet) // 统一获取日期的属性,记得替换成你实际的日期字段 var date: Date { switch self { case .article(let model): // 假设你的LocationModel有date属性,如果是字符串要先转成Date return model.date case .tweet(let tweet): // TwitterKit的TWTRTweet自带createdAt日期属性 return tweet.createdAt } } }
2. 合并并排序所有数据
新增一个统一的数据源数组,每当网页数据或推文数据下载完成后,就把两者合并、排序,最后刷新表格:
// 新增统一的数据源数组 var unifiedFeedItems: [UnifiedFeedItem] = [] // 修改网页数据下载完成的方法 func itemsDownloaded(items: NSArray) { feedItems = items as! [LocationModel] updateAndSortUnifiedFeed() } // 修改推文数据下载完成的方法 func twitterDownloaded(items: [Any]) { tweetData = TWTRTweet.tweets(withJSONArray: items) as! [TWTRTweet] updateAndSortUnifiedFeed() } // 专门处理合并和排序的私有方法 private func updateAndSortUnifiedFeed() { var tempItems: [UnifiedFeedItem] = [] // 把网页数据转成UnifiedFeedItem类型加入临时数组 tempItems.append(contentsOf: feedItems.map { .article($0) }) // 把推文数据转成UnifiedFeedItem类型加入临时数组 tempItems.append(contentsOf: tweetData.map { .tweet($0) }) // 按日期降序排序(最新的内容排在最前面),要升序就把>换成< unifiedFeedItems = tempItems.sorted { $0.date > $1.date } // 可选:按日期过滤,比如只显示近7天的内容 let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: Date())! unifiedFeedItems = unifiedFeedItems.filter { $0.date >= sevenDaysAgo } self.tableView.reloadData() }
3. 修改TableView的数据源方法
现在表格的行数和单元格渲染都基于统一的数据源,不用再区分前后段了:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return unifiedFeedItems.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let currentItem = unifiedFeedItems[indexPath.row] switch currentItem { case .article(let article): let cell = tableView.dequeueReusableCell(withIdentifier: "articleCell", for: indexPath) as! articleTableViewCell // 这里写你原来的网页单元格配置逻辑,比如: // cell.titleLabel.text = article.title // cell.dateLabel.text = yourDateFormatter.string(from: article.date) return cell case .tweet(let tweet): let cell = tableView.dequeueReusableCell(withIdentifier: "twitterCell", for: indexPath) as! CustomTableViewCell // 这里写你原来的推文单元格配置逻辑,比如: // let tweetView = TWTRTweetView(tweet: tweet) // tweetView.frame = cell.contentView.bounds // cell.contentView.addSubview(tweetView) return cell } }
小提示
- 如果你的
LocationModel里的日期是字符串格式,记得先写一个DateFormatter把它转成Date类型,不然排序会出错。 - 排序逻辑可以根据需求调整,比如按日期升序(最早的在前),只需要修改
sorted里的比较符号。
内容的提问来源于stack exchange,提问作者Mus Harlem
相关产品推荐
相关产品推荐

