通过Unwind Segue填充TableView时重复生成同日期分区求助
解决TableView添加同日期数据时重复生成分区的问题
你的问题核心在于sortByDate()方法的逻辑漏洞:每次调用该方法时,没有清空已有的sections数组,而是直接往里面追加新生成的分区对象。旧分区未被清理,新的同日期分区又被重复添加,最终导致界面出现重复的日期分区。
下面是具体的修复和优化方案:
1. 先清空旧分区,再生成新分区
在sortByDate()方法开头添加清空逻辑,确保每次都基于最新的sessions数据生成全新的分区集合:
func sortByDate() { sections.removeAll() // 关键步骤:清空原有分区 let datesInSessions = sessions.reduce(into: Set<Date>()) { result, session in guard let dateModel = session.dateModel else { return } let dateInSession = Calendar.current.startOfDay(for: dateModel) result.insert(dateInSession) } for dateInSession in datesInSessions { let dateComp = Calendar.current.dateComponents([.year, .month, .day], from: dateInSession) let sortedContent = sessions.compactMap { session in guard let dateModel = session.dateModel else { return nil } let contComp = Calendar.current.dateComponents([.year, .month, .day], from: dateModel) return contComp == dateComp ? session : nil } // 给分区内的Session按开始时间排序 let sortedContentByTime = sortedContent.sorted { $0.timeBegModel ?? Date() < $1.timeBegModel ?? Date() } let newSection = Section(sectionDate: dateInSession, sessions: sortedContentByTime) sections.append(newSection) } // 给分区按日期排序(让最新日期的分区排在前面) sections.sort { $0.sectionDate > $1.sectionDate } }
2. 优化分组逻辑:用Dictionary简化代码
可以利用Swift原生的grouping方法直接按日期分组,代码更简洁高效,避免双重循环的冗余:
func sortByDate() { sections.removeAll() // 按"当天起始时间"作为key,对Session分组 let groupedSessions = Dictionary(grouping: sessions) { session -> Date in guard let dateModel = session.dateModel else { return Date() } return Calendar.current.startOfDay(for: dateModel) } // 将分组结果转换为Section数组 sections = groupedSessions.map { (date, sessionsInGroup) in let sortedSessions = sessionsInGroup.sorted { $0.timeBegModel ?? Date() < $1.timeBegModel ?? Date() } return Section(sectionDate: date, sessions: sortedSessions) } // 分区按日期排序 sections.sort { $0.sectionDate > $1.sectionDate } }
3. 修复强制解包的崩溃隐患
你代码中大量使用!强制解包可选型(比如$0.timeBegModel!),一旦某个Session的可选属性为nil,会直接导致应用崩溃。上面的优化代码已经通过guard let和??默认值处理了这个问题,避免崩溃风险。
4. 简化Unwind Segue中的排序逻辑
原代码中先对sessions数组排序是多余的,因为sortByDate()里已经会对每个分区内的Session按时间排序,可以直接移除:
@IBAction func unwindToMainVC(segue: UIStoryboardSegue) { guard let vc = segue.source as? AddSessionVC else { return } guard let date = vc.dateDP?.date, let timeBeg = vc.timeBegDP?.date, let timeEnd = vc.timeEndDP?.date, let session = vc.sessionTF.text, let venue = vc.venueTF.text else { return } let newSession = Session(dateModel: date, timeBegModel: timeBeg, timeEndModel: timeEnd, sessionModel: session, venueModel: venue) sessions.append(newSession) sortByDate() tableView.reloadData() }
内容的提问来源于stack exchange,提问作者CalebGates
相关产品推荐
相关产品推荐

